Also works on core dumps, in the form of:
java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize $JAVA_HOME/bin/java core.xxx
$ java -version | |
java version "1.6.0_30" | |
Java(TM) SE Runtime Environment (build 1.6.0_30-b12) | |
Java HotSpot(TM) 64-Bit Server VM (build 20.5-b03, mixed mode) | |
$ javac -classpath $JAVA_HOME/lib/sa-jdi.jar DirectMemorySize.java | |
$ jps | |
18486 GroovyStarter | |
23135 Jps | |
$ java -classpath .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize `pgrep java` | |
Attaching to process ID 18486, please wait... | |
Debugger attached successfully. | |
Server compiler detected. | |
JVM version is 20.5-b03 | |
NIO direct memory: (in bytes) | |
reserved size = 0.000000 MB (0 bytes) | |
max size = 4069.000000 MB (4266655744 bytes) |
[sajia@211 temp]$ java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize | |
Usage: java directMemorySize [option] <pid> | |
(to connect to a live java process) | |
or java directMemorySize [option] <executable> <core> | |
(to connect to a core file) | |
or java directMemorySize [option] [server_id@]<remote server IP or hostname> | |
(to connect to a remote debug server) | |
where option must be one of: | |
-e to print the actual size malloc'd | |
-v to print verbose info of every live DirectByteBuffer allocated from Java | |
-h | -help to print this help message | |
[sajia@211 temp]$ java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize `pgrep -u sajia java` | |
Attaching to process ID 7381, please wait... | |
Debugger attached successfully. | |
Server compiler detected. | |
JVM version is 20.5-b03 | |
NIO direct memory: (in bytes) | |
reserved size = 0.000003 MB (3 bytes) | |
max size = 7152.000000 MB (7499415552 bytes) | |
[sajia@211 temp]$ java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize -e `pgrep -u sajia java` | |
Attaching to process ID 7381, please wait... | |
Debugger attached successfully. | |
Server compiler detected. | |
JVM version is 20.5-b03 | |
NIO direct memory: (in bytes) | |
reserved size = 0.000003 MB (3 bytes) | |
max size = 7152.000000 MB (7499415552 bytes) | |
Finding object size using Printezis bits and skipping over... | |
Finding object size using Printezis bits and skipping over... | |
NIO direct memory malloc'd size: 0.007815 MB (8195 bytes) | |
[sajia@211 temp]$ time java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize `pgrep -u sajia java` | |
Attaching to process ID 7381, please wait... | |
Debugger attached successfully. | |
Server compiler detected. | |
JVM version is 20.5-b03 | |
NIO direct memory: (in bytes) | |
reserved size = 0.000003 MB (3 bytes) | |
max size = 7152.000000 MB (7499415552 bytes) | |
real 0m0.401s | |
user 0m0.503s | |
sys 0m0.057s | |
[sajia@211 temp]$ time java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize -e `pgrep -u sajia java` | |
Attaching to process ID 7381, please wait... | |
Debugger attached successfully. | |
Server compiler detected. | |
JVM version is 20.5-b03 | |
NIO direct memory: (in bytes) | |
reserved size = 0.000003 MB (3 bytes) | |
max size = 7152.000000 MB (7499415552 bytes) | |
Finding object size using Printezis bits and skipping over... | |
Finding object size using Printezis bits and skipping over... | |
NIO direct memory malloc'd size: 0.007815 MB (8195 bytes) | |
real 0m4.822s | |
user 0m2.095s | |
sys 0m3.216s | |
[sajia@211 temp]$ time java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize -e -v `pgrep -u sajia java` | |
Attaching to process ID 7381, please wait... | |
Debugger attached successfully. | |
Server compiler detected. | |
JVM version is 20.5-b03 | |
NIO direct memory: (in bytes) | |
reserved size = 0.000003 MB (3 bytes) | |
max size = 7152.000000 MB (7499415552 bytes) | |
Currently allocated direct buffers: | |
0x00002aaab021df10: capacity = 0.000001 MB (1 bytes), mallocSize = 0.003907 MB (4097 bytes) | |
0x00002aaab0843310: capacity = 0.000002 MB (2 bytes), mallocSize = 0.003908 MB (4098 bytes) | |
Finding object size using Printezis bits and skipping over... | |
Finding object size using Printezis bits and skipping over... | |
NIO direct memory malloc'd size: 0.007815 MB (8195 bytes) | |
real 0m5.097s | |
user 0m2.164s | |
sys 0m3.426s | |
[sajia@211 temp]$ |
[sajia@xxx164 gist]$ sudo -u admin java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize -e `pgrep -u admin java` | grep -v 'Finding object' | |
Attaching to process ID 2499, please wait... | |
Debugger attached successfully. | |
Server compiler detected. | |
JVM version is 20.0-b12-internal | |
NIO direct memory: (in bytes) | |
reserved size = 907.541405 MB (951626136 bytes) | |
max size = 3925.375000 MB (4116054016 bytes) | |
NIO direct memory malloc'd size: 910.697655 MB (954935704 bytes) |
import java.io.*; | |
import java.util.*; | |
import sun.jvm.hotspot.memory.*; | |
import sun.jvm.hotspot.oops.*; | |
import sun.jvm.hotspot.debugger.*; | |
import sun.jvm.hotspot.runtime.*; | |
import sun.jvm.hotspot.tools.*; | |
import sun.jvm.hotspot.utilities.*; | |
public class DirectMemorySize extends Tool { | |
private boolean exactMallocMode; | |
private boolean verbose; | |
public DirectMemorySize(boolean exactMallocMode, boolean verbose) { | |
this.exactMallocMode = exactMallocMode; | |
this.verbose = verbose; | |
} | |
public void run() { | |
// Ready to go with the database... | |
try { | |
long reservedMemory = getStaticLongFieldValue("java.nio.Bits", "reservedMemory"); | |
long directMemory = getStaticLongFieldValue("sun.misc.VM", "directMemory"); | |
System.out.println("NIO direct memory: (in bytes)"); | |
System.out.printf(" reserved size = %f MB (%d bytes)\n", toM(reservedMemory), reservedMemory); | |
System.out.printf(" max size = %f MB (%d bytes)\n", toM(directMemory), directMemory); | |
if (verbose) { | |
System.out.println("Currently allocated direct buffers:"); | |
} | |
if (exactMallocMode || verbose) { | |
final long pageSize = getStaticIntFieldValue("java.nio.Bits", "pageSize"); | |
ObjectHeap heap = VM.getVM().getObjectHeap(); | |
InstanceKlass deallocatorKlass = | |
SystemDictionaryHelper.findInstanceKlass("java.nio.DirectByteBuffer$Deallocator"); | |
final LongField addressField = (LongField) deallocatorKlass.findField("address", "J"); | |
final IntField capacityField = (IntField) deallocatorKlass.findField("capacity", "I"); | |
final int[] countHolder = new int[1]; | |
heap.iterateObjectsOfKlass(new DefaultHeapVisitor() { | |
public boolean doObj(Oop oop) { | |
long address = addressField.getValue(oop); | |
if (address == 0) return false; // this deallocator has already been run | |
long capacity = capacityField.getValue(oop); | |
long mallocSize = capacity + pageSize; | |
countHolder[0]++; | |
if (verbose) { | |
System.out.printf(" 0x%016x: capacity = %f MB (%d bytes)," | |
+ " mallocSize = %f MB (%d bytes)\n", | |
address, toM(capacity), capacity, | |
toM(mallocSize), mallocSize); | |
} | |
return false; | |
} | |
}, deallocatorKlass, false); | |
if (exactMallocMode) { | |
long totalMallocSize = reservedMemory + pageSize * countHolder[0]; | |
System.out.printf("NIO direct memory malloc'd size: %f MB (%d bytes)\n", | |
toM(totalMallocSize), totalMallocSize); | |
} | |
} | |
} catch (AddressException e) { | |
System.err.println("Error accessing address 0x" | |
+ Long.toHexString(e.getAddress())); | |
e.printStackTrace(); | |
} | |
} | |
public static long getStaticLongFieldValue(String className, String fieldName) { | |
InstanceKlass klass = SystemDictionaryHelper.findInstanceKlass(className); | |
LongField field = (LongField) klass.findField(fieldName, "J"); | |
return field.getValue(klass); // on JDK7 use: field.getValue(klass.getJavaMirror()); | |
} | |
public static int getStaticIntFieldValue(String className, String fieldName) { | |
InstanceKlass klass = SystemDictionaryHelper.findInstanceKlass(className); | |
IntField field = (IntField) klass.findField(fieldName, "I"); | |
return field.getValue(klass); // on JDK7 use: field.getValue(klass.getJavaMirror()); | |
} | |
public static double toM(long value) { | |
return value / (1024 * 1024.0); | |
} | |
public String getName() { | |
return "directMemorySize"; | |
} | |
protected void printFlagsUsage() { | |
System.out.println(" -e\tto print the actual size malloc'd"); | |
System.out.println(" -v\tto print verbose info of every live DirectByteBuffer allocated from Java"); | |
super.printFlagsUsage(); | |
} | |
public static void main(String[] args) { | |
boolean exactMallocMode = false; | |
boolean verbose = false; | |
// argument processing logic copied from sun.jvm.hotspot.tools.JStack | |
int used = 0; | |
for (String arg : args) { | |
if ("-e".equals(arg)) { | |
exactMallocMode = true; | |
used++; | |
} else if ("-v".equals(arg)) { | |
verbose = true; | |
used++; | |
} | |
} | |
if (used != 0) { | |
args = Arrays.copyOfRange(args, used, args.length); | |
} | |
DirectMemorySize tool = new DirectMemorySize(exactMallocMode, verbose); | |
tool.start(args); | |
tool.stop(); | |
} | |
} |
Package "sun.jvm.hotspot.memory.*" is in the $JAVA_HOME/lib/sa-jdi.jar. Did you add this jar to CLASSPATH?
收藏了
学习
HI 我执行完一次之后。kill -9 DirectMemorySize 的运行进城后,想再次使用就一直连接不上去 。这是为什么呢?
使用-e
或-v
参数时只显示和不加参数时同样的信息,上面例子上给出的额外信息一直长时间无法显示,是什么原因?
[root@cass047202 ~]# java -classpath .:/usr/install/java/lib/sa-jdi.jar DirectMemorySize -e 2904
Attaching to process ID 2904, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.51-b03
NIO direct memory: (in bytes)
reserved size = 32686.010643 MB (34273766296 bytes)
max size = 27566.686493 MB (28905765856 bytes)
使用环境 CentOS 6.5 64bit,物理内存32G,Jdk7,Xmx8G
还有一个问题,按你这篇文章http://hllvm.group.iteye.com/group/topic/27945 提到的,如果参数 -XX:MaxDirectMemorySize
没有设置,默认应该是约等了-Xmx8g
这个值,为何这里显示是将近27G?
Any love to port this to JDK8?
he is addicted for yaba for long time he always motivated new one comer.
can it works on java8?
tool.run(args) modify to tool.execute(args);
同问 它可以在java8上运行吗
irectMemorySize.java:3: package sun.jvm.hotspot.memory does not exist
import sun.jvm.hotspot.memory.*;
^
Couldn't find this package from some reason. Running on Mac OSX