简体   繁体   English

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

[英]Can heap dump be created for analyzing memory leak without garbage collection?

We have some memory leak issues on VMs in production which are running Java applications, the Old Gen heap usage grows fast every day, so I want to create heap dump to analyze it. 我们在生产中运行Java应用程序的虚拟机上存在一些内存泄漏问题,旧的Gen堆使用量每天都在快速增长,所以我想创建堆转储来分析它。

However, I noticed that VisualVM will perform full GC before heap dump which will clean the Old Gen, in that case, the heap dump would be useless. 但是,我注意到VisualVM将在堆转储之前执行完整的GC,这将清除旧的Gen,在这种情况下,堆转储将是无用的。

I also tried to use the following command: 我还尝试使用以下命令:

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

It will also trigger a full GC. 它还将触发完整的GC。

May I ask if there is a way that heap dump can be created without full GC (or without GC)? 请问是否有一种方法可以在没有完整GC(或没有GC)的情况下创建堆转储? Or is there any better way to analyze the memory leak? 或者有没有更好的方法来分析内存泄漏?

JDK version: 1.7.0_45 JDK版本:1.7.0_45

Thanks. 谢谢。

The answer marked as correct isn't correct anymore. 标记为正确的答案不再正确。 As Sumit says, it will cause a Full GC only when the live option is used (in both histo & dump operations). 正如Sumit所说,只有在使用live选项时(在histo和dump操作中)它才会导致Full GC。

Java 7 and Java 8 have this option Java 7Java 8具有此选项

-histo[:live] -histo [:生活]

Prints a histogram of the heap. 打印堆的直方图。 For each Java class, the number of objects, memory size in bytes, and the fully qualified class names are printed. 对于每个Java类,将打印对象数,内存大小(以字节为单位)和完全限定的类名。 The JVM internal class names are printed with an asterisk (*) prefix. JVM内部类名称使用星号(*)前缀打印。 If the live suboption is specified, then only active objects are counted. 如果指定了实时子选项,则仅计算活动对象。


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

Dumps the Java heap in hprof binary format to filename. 将hprof二进制格式的Java堆转储为filename。 The live suboption is optional, but when specified, only the active objects in the heap are dumped . 实时子选项是可选的,但是在指定时,只会转储堆中的活动对象 To browse the heap dump, you can use the jhat(1) command to read the generated file. 要浏览堆转储,可以使用jhat(1)命令读取生成的文件。

You could aldo use the jcmd command with the operation GC.heap_dump and the option -all 您可以使用带有GC.heap_dump操作的jcmd命令和选项-all

GC.heap_dump Generate a HPROF format dump of the Java heap. GC.heap_dump生成Java堆的HPROF格式转储。 Impact: High: Depends on Java heap size and content. 影响:高:取决于Java堆大小和内容。 Request a full GC unless the '-all' option is specified. 除非指定了“-all”选项,否则请求完整的GC。

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

Syntax : GC.heap_dump [options] 语法:GC.heap_dump [options]

Arguments: filename : Name of the dump file (STRING, no default value) 参数:filename:转储文件的名称(STRING,无默认值)

Options: (options must be specified using the or = syntax) -all : [optional] Dump all objects, including unreachable objects (BOOLEAN, false) 选项:(必须使用or =语法指定选项)-all:[可选]转储所有对象,包括无法访问的对象(BOOLEAN,false)

Example: jcmd 3181 GC.heap_dump -all dump 示例: jcmd 3181 GC.heap_dump -all dump

You could add the -XX:+PrintGCDetails flag to see if a Full GC is hapenning. 您可以添加-XX:+PrintGCDetails标志以查看Full GC是否正在开启。 For example, when I use jcmd without -all I see something like this. 例如,当我使用没有-all的jcmd时,我看到这样的东西。

200,658: [Full GC (Heap Dump Initiated GC) 200,658: [CMS: 5040K->4158K(18432K), 0,0171885 secs] 11239K->4158K(25856K), [Metaspace: 18053K->18053K(1064960K)], 0,0173941 secs] [Times: user=0,01 sys=0,00, real=0,02 secs] 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秒]

You can trigger HeapDump using JMX bean HotSpotDiagnostic and second parameter of method set to false. 您可以使用JMX bean HotSpotDiagnostic触发HeapDump,将方法的第二个参数设置为false。

See this answer for a more detailed response: https://stackoverflow.com/a/35575793/236528 有关更详细的响应,请参阅此答案: https//stackoverflow.com/a/35575793/236528

To create a heap dump, there will be a Full GC. 要创建堆转储,将有一个Full GC。 The same applies when creating Class histogram out of heap. 从堆中创建类直方图时也是如此。

If you want to analyze memory leak between Full GCs, then probably memory profiling using a Java profiler (Mission Control, jProfiler, etc) is your only option. 如果要分析Full GC之间的内存泄漏,那么使用Java分析器(Mission Control,jProfiler等)进行内存分析可能是您唯一的选择。

See this Q/A for Java Mission Control Heap Profile . 有关Java Mission Control堆配置文件,请参阅此Q / A.

Just remove live from the option and you should be good. 只需从选项中删除live即可,你应该很好。 When you're supplying "live" option to jmap. 当您向jmap提供“live”选项时。 you're forcing JVM to run a Full GC and capture those supposed to be "live". 你迫使JVM运行Full GC并捕获那些应该是“实时”的。 use jmap -dump:format=b,file=hd.hprof rather. 使用jmap -dump:format = b,file = hd.hprof。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM