1 /**
2 * Copyright 2011 The Apache Software Foundation
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package org.apache.hadoop.hbase.util;
22
23 import java.lang.management.ManagementFactory;
24 import java.lang.management.RuntimeMXBean;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.nio.ByteBuffer;
28 import java.util.List;
29
30 import com.google.common.base.Preconditions;
31
32 public class DirectMemoryUtils {
33 /**
34 * @return the setting of -XX:MaxDirectMemorySize as a long. Returns 0 if
35 * -XX:MaxDirectMemorySize is not set.
36 */
37
38 public static long getDirectMemorySize() {
39 RuntimeMXBean RuntimemxBean = ManagementFactory.getRuntimeMXBean();
40 List<String> arguments = RuntimemxBean.getInputArguments();
41 long multiplier = 1; //for the byte case.
42 for (String s : arguments) {
43 if (s.contains("-XX:MaxDirectMemorySize=")) {
44 String memSize = s.toLowerCase()
45 .replace("-xx:maxdirectmemorysize=", "").trim();
46
47 if (memSize.contains("k")) {
48 multiplier = 1024;
49 }
50
51 else if (memSize.contains("m")) {
52 multiplier = 1048576;
53 }
54
55 else if (memSize.contains("g")) {
56 multiplier = 1073741824;
57 }
58 memSize = memSize.replaceAll("[^\\d]", "");
59
60 long retValue = Long.parseLong(memSize);
61 return retValue * multiplier;
62 }
63
64 }
65 return 0;
66 }
67
68 /**
69 * DirectByteBuffers are garbage collected by using a phantom reference and a
70 * reference queue. Every once a while, the JVM checks the reference queue and
71 * cleans the DirectByteBuffers. However, as this doesn't happen
72 * immediately after discarding all references to a DirectByteBuffer, it's
73 * easy to OutOfMemoryError yourself using DirectByteBuffers. This function
74 * explicitly calls the Cleaner method of a DirectByteBuffer.
75 *
76 * @param toBeDestroyed
77 * The DirectByteBuffer that will be "cleaned". Utilizes reflection.
78 *
79 */
80 public static void destroyDirectByteBuffer(ByteBuffer toBeDestroyed)
81 throws IllegalArgumentException, IllegalAccessException,
82 InvocationTargetException, SecurityException, NoSuchMethodException {
83
84 Preconditions.checkArgument(toBeDestroyed.isDirect(),
85 "toBeDestroyed isn't direct!");
86
87 Method cleanerMethod = toBeDestroyed.getClass().getMethod("cleaner");
88 cleanerMethod.setAccessible(true);
89 Object cleaner = cleanerMethod.invoke(toBeDestroyed);
90 Method cleanMethod = cleaner.getClass().getMethod("clean");
91 cleanMethod.setAccessible(true);
92 cleanMethod.invoke(cleaner);
93
94 }
95 }