1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver;
20
21 import java.lang.management.ManagementFactory;
22 import java.lang.management.MemoryUsage;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.hbase.classification.InterfaceAudience;
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.hbase.Chore;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.Server;
31 import org.apache.hadoop.hbase.util.Threads;
32
33 import com.google.common.annotations.VisibleForTesting;
34
35
36
37
38 @InterfaceAudience.Private
39 public class HeapMemoryManager {
40 private static final Log LOG = LogFactory.getLog(HeapMemoryManager.class);
41
42
43 public static final String HBASE_RS_HEAP_MEMORY_TUNER_PERIOD =
44 "hbase.regionserver.heapmemory.tuner.period";
45 public static final int HBASE_RS_HEAP_MEMORY_TUNER_DEFAULT_PERIOD = 60 * 1000;
46
47 private float heapOccupancyPercent;
48
49 private Server server;
50 private HeapMemoryChore heapMemChore = null;
51 private final int defaultChorePeriod;
52 private final float heapOccupancyLowWatermark;
53
54 public static HeapMemoryManager create(Server server) {
55 return new HeapMemoryManager(server);
56 }
57
58 @VisibleForTesting
59 HeapMemoryManager(Server server) {
60 Configuration conf = server.getConfiguration();
61 this.server = server;
62 this.defaultChorePeriod = conf.getInt(HBASE_RS_HEAP_MEMORY_TUNER_PERIOD,
63 HBASE_RS_HEAP_MEMORY_TUNER_DEFAULT_PERIOD);
64 this.heapOccupancyLowWatermark = conf.getFloat(HConstants.HEAP_OCCUPANCY_LOW_WATERMARK_KEY,
65 HConstants.DEFAULT_HEAP_OCCUPANCY_LOW_WATERMARK);
66 }
67
68 public void start() {
69 this.heapMemChore = new HeapMemoryChore();
70 Threads.setDaemonThreadRunning(heapMemChore.getThread());
71 }
72
73 public void stop() {
74
75 this.heapMemChore.interrupt();
76 }
77
78
79
80
81 public float getHeapOccupancyPercent() {
82 return this.heapOccupancyPercent;
83 }
84
85 private class HeapMemoryChore extends Chore {
86 private boolean alarming = false;
87
88 public HeapMemoryChore() {
89 super(server.getServerName() + "-HeapMemoryChore", defaultChorePeriod, server);
90 }
91
92 @Override
93 protected void sleep() {
94 if (!alarming) {
95 super.sleep();
96 } else {
97
98 try {
99 Thread.sleep(1000);
100 } catch (InterruptedException e) {
101
102 Thread.currentThread().interrupt();
103 }
104 }
105 }
106
107 @Override
108 protected void chore() {
109
110 MemoryUsage memUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
111 heapOccupancyPercent = (float)memUsage.getUsed() / (float)memUsage.getCommitted();
112
113 if (heapOccupancyPercent >= heapOccupancyLowWatermark) {
114 if (!alarming) {
115 LOG.warn("heapOccupancyPercent " + heapOccupancyPercent +
116 " is above heap occupancy alarm watermark (" + heapOccupancyLowWatermark + ")");
117 alarming = true;
118 }
119 } else {
120 if (alarming) {
121 LOG.info("heapOccupancyPercent " + heapOccupancyPercent +
122 " is now below the heap occupancy alarm watermark (" +
123 heapOccupancyLowWatermark + ")");
124 alarming = false;
125 }
126 }
127 }
128 }
129 }