在进行OOM分析或者线上经常FullGC时,需要我们dump内存文件分析,不同情况下需要使用不同的dump方法。
获取程序的pid有两种方法:
执行ps -ef | grep 程序名在java/bin 文件中执行jps1.可以使用jmap工具:
Jmap命令是一个多功能的命令。它可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。
jmap -dump:file=文件名 $pid 但是当疯狂FullGC时 dump出的文件可能无法分析。
2.使用jcmd工具:
jcmd $pid GC.heap_dump 文件名
这个和方法1的不同是 这个工具只保留存活的对象。详见:链接
在启动时添加JVM参数
-XX:+HeapDumpBeforeFullGC -XX:+HeapDumpAfterFullGC -XX:HeapDumpPath=e:\dump
运行时修改HeapDumpBeforeFullGC
本例以HeapDumpBeforeFullGC讲解其它可以设置的参数请执行以下命令:
java -XX:+PrintFlagsFinal -version | grep manageable使用jinfo工具
jinfo是一个命令行工具,通过这个工具可以获取JAVA进程运行时的一些信息,通过使用jinfo 和一些参数,可以动态修改JAVA进程的虚拟机参数
jinfo -flag +HeapDumpBeforeFullGC $pid
如果执行完想关闭:
jinfo -flag -HeapDumpBeforeFullGC $pid
使用jconsole工具
JConsole(Java™ 监控和管理控制台)是一个允许用户监控并管理 Java 应用程序行为的图形工具。
使用JConsole工具调用JMX服务的com.sum.management.HotSpotDiagnostic.setVMOption方法来实现。
第一个参数为HeapDumpBeforeFullGC, 第二个参数为true表示在Full GC前进行dump.
第一个参数为HeapDumpAfterFullGC, 第二个参数为true表示在Full GC后进行dump
使用jcmd 工具
jcmd 不仅可以立即dump文件也能修改JVM参数。
jcmd $pid VM.set_flag HeapDumpAfterFullGC true
如果你排查的是一直在FullGC的gc问题,你Dump下来的堆往往是正处于FullGC中,可能会导致分析失败 。此时我们可以使用gbd 这款c++程序的调试神器。
找到java进程,gdb attach上去, 例如 gdb -p $pid
找到这个HeapDumpBeforeFullGC的地址(这个flag如果为true,会在FullGC之前做HeapDump,默认是false)
(gdb) p &HeapDumpBeforeFullGC $2 = (<data variable, no debug info> *) 0x7f7d50fc660f <HeapDumpBeforeFullGC>Copy
然后把他设置为true,这样下次FGC之前就会生成一份dump文件
(gdb) set *0x7f7d50fc660f = 1 (gdb) quitCopy
最后,等一会,等下次FullGC触发,你就有HeapDump了! (如果没有指定heapdump的名字,默认是 java_pidxxx.hprof)
(PS. jstat -gcutil pid 可以查看gc的概况)
(操作完成后记得gdb上去再设置回去,不然可能一直fullgc,导致把磁盘打满)