是否可以创建堆转储以分析内存泄漏而无需垃圾回收?

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

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

我还尝试使用以下命令:

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

它还将触发完整的GC。

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

JDK版本:1.7.0_45

谢谢。

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

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

有关Java Mission Control堆配置文件,请参阅此Q / A.

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

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

只需从选项中删除live即可,你应该很好。 当您向jmap提供“live”选项时。 你迫使JVM运行Full GC并捕获那些应该是“实时”的。 使用jmap -dump:format = b,file = hd.hprof。

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

Java 7和Java 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秒]