可以创建堆转储来分析内存泄漏而不进行垃圾回收吗?

zhe*_*gyu 11 java garbage-collection memory-leaks

我们在生产中运行Java应用程序的虚拟机上存在一些内存泄漏问题,旧的Gen堆使用量每天都在快速增长,所以我想创建堆转储来分析它.

但是,我注意到VisualVM将在堆转储之前执行完整的GC,这将清除旧的Gen,在这种情况下,堆转储将是无用的.

我还尝试使用以下命令:

jmap -dump:live,format = b,file = heap.bin

它还将触发完整的GC.

请问是否有一种方法可以在没有完整GC(或没有GC)的情况下创建堆转储?或者有没有更好的方法来分析内存泄漏?

JDK版本:1.7.0_45

谢谢.

gab*_*ssi 12

标记为正确的答案不再正确.正如Sumit所说,只有在使用live选项时(在histo和dump操作中)它才会导致Full GC.

Java 7Java 8具有此选项

-histo [:生活]

打印堆的直方图.对于每个Java类,将打印对象数,内存大小(以字节为单位)和完全限定的类名.JVM内部类名称使用星号(*)前缀打印.如果指定了实时子选项,则仅计算活动对象.


-dump:[live,] format = b,file = filename

将hprof二进制格式的Java堆转储为filename.实时子选项是可选的,但是在指定时,只会转储堆中的活动对象.要浏览堆转储,可以使用jhat(1)命令读取生成的文件.

您可以使用带有GC.heap_dump操作的jcmd命令和选项-all

GC.heap_dump生成Java堆的HPROF格式转储.影响:高:取决于Java堆大小和内容.除非指定'-all'选项,否则请求完整的GC.

权限:java.lang.management.ManagementPermission(monitor)

语法:GC.heap_dump [options]

参数:filename:转储文件的名称(STRING,无默认值)

选项:(必须使用or =语法指定选项)-all:[可选]转储所有对象,包括无法访问的对象(BOOLEAN,false)

例: jcmd 3181 GC.heap_dump -all dump

您可以添加-XX:+PrintGCDetails标志以查看Full GC是否正在开启.例如,当我使用没有-all的jcmd时,我看到这样的东西.

200,658:[全GC(堆转储启动GC)200,658:[CMS:5040K-> 4158K(18432K),0,0171885秒] 11239K-> 4158K(25856K),[Metaspace:18053K-> 18053K(1064960K)],0 ,0173941秒] [时间:用户= 0,01 sys = 0,00,实际= 0,02秒]


Amr*_*dey 7

您可以使用JMX bean HotSpotDiagnostic触发HeapDump,将方法的第二个参数设置为false.

有关更详细的响应,请参阅此答案:https: //stackoverflow.com/a/35575793/236528


Ale*_*leš 6

要创建堆转储,将有一个Full GC.从堆中创建类直方图时也是如此.

如果要分析Full GCs之间的内存泄漏,那么使用Java Profiler(Mission Control,jProfiler等)进行内存分析可能是您唯一的选择.

看到此Q/A Java的任务控制堆档案.