1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.util;
21
22 import java.lang.management.ManagementFactory;
23 import java.lang.management.RuntimeMXBean;
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.nio.ByteBuffer;
27 import java.util.List;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.hadoop.classification.InterfaceAudience;
32 import org.apache.hadoop.classification.InterfaceStability;
33
34 import com.google.common.base.Preconditions;
35
36 import javax.management.JMException;
37 import javax.management.MBeanServer;
38 import javax.management.MalformedObjectNameException;
39 import javax.management.ObjectName;
40
41
42
43
44 @InterfaceAudience.Private
45 @InterfaceStability.Evolving
46 public class DirectMemoryUtils {
47 private static final Log LOG = LogFactory.getLog(DirectMemoryUtils.class);
48 private static final MBeanServer beanServer;
49 private static final ObjectName nioDirectPool;
50
51 static {
52
53
54 ObjectName n = null;
55 MBeanServer s = null;
56 try {
57 n = new ObjectName("java.nio:type=BufferPool,name=direct");
58 } catch (MalformedObjectNameException e) {
59 LOG.warn("Unable to initialize ObjectName for DirectByteBuffer allocations.");
60 } finally {
61 nioDirectPool = n;
62 }
63 if (nioDirectPool != null) {
64 s = ManagementFactory.getPlatformMBeanServer();
65 }
66 beanServer = s;
67 }
68
69
70
71
72
73 public static long getDirectMemorySize() {
74 RuntimeMXBean runtimemxBean = ManagementFactory.getRuntimeMXBean();
75 List<String> arguments = runtimemxBean.getInputArguments();
76 long multiplier = 1;
77 for (String s : arguments) {
78 if (s.contains("-XX:MaxDirectMemorySize=")) {
79 String memSize = s.toLowerCase()
80 .replace("-xx:maxdirectmemorysize=", "").trim();
81
82 if (memSize.contains("k")) {
83 multiplier = 1024;
84 }
85
86 else if (memSize.contains("m")) {
87 multiplier = 1048576;
88 }
89
90 else if (memSize.contains("g")) {
91 multiplier = 1073741824;
92 }
93 memSize = memSize.replaceAll("[^\\d]", "");
94
95 long retValue = Long.parseLong(memSize);
96 return retValue * multiplier;
97 }
98 }
99 return 0;
100 }
101
102
103
104
105 public static long getDirectMemoryUsage() {
106 if (beanServer == null || nioDirectPool == null) return 0;
107 try {
108 Long value = (Long) beanServer.getAttribute(nioDirectPool, "MemoryUsed");
109 return value == null ? 0 : value;
110 } catch (JMException e) {
111 LOG.debug("Failed to retrieve nio.BufferPool direct MemoryUsed");
112 return 0;
113 }
114 }
115
116
117
118
119
120
121
122
123
124
125
126
127
128 public static void destroyDirectByteBuffer(ByteBuffer toBeDestroyed)
129 throws IllegalArgumentException, IllegalAccessException,
130 InvocationTargetException, SecurityException, NoSuchMethodException {
131
132 Preconditions.checkArgument(toBeDestroyed.isDirect(),
133 "toBeDestroyed isn't direct!");
134
135 Method cleanerMethod = toBeDestroyed.getClass().getMethod("cleaner");
136 cleanerMethod.setAccessible(true);
137 Object cleaner = cleanerMethod.invoke(toBeDestroyed);
138 Method cleanMethod = cleaner.getClass().getMethod("clean");
139 cleanMethod.setAccessible(true);
140 cleanMethod.invoke(cleaner);
141 }
142 }