Java 可以创建堆转储来分析内存泄漏而不进行垃圾收集吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23393480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can heap dump be created for analyzing memory leak without garbage collection?
提问by zhengyu
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 应用程序的生产中的 VM 上存在一些内存泄漏问题,Old 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,这将清除 Old 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)? Or is there any better way to analyze the memory leak?
请问有没有办法不用full GC(或者不用GC)就可以创建heap dump?或者有没有更好的方法来分析内存泄漏?
JDK version: 1.7.0_45
JDK 版本:1.7.0_45
Thanks.
谢谢。
采纳答案by Ale?
To create a heap dump, there will be a Full GC. The same applies when creating Class histogram out of heap.
要创建堆转储,将有一个 Full GC。这同样适用于在堆外创建类直方图。
If you want to analyze memory leak between Full GCs, then probably memory profilingusing a Java profiler (Mission Control, jProfiler, etc) is your only option.
如果您想分析 Full GC 之间的内存泄漏,那么使用 Java 分析器(任务控制、jProfiler 等)进行内存分析可能是您唯一的选择。
See this Q/A for Java Mission Control Heap Profile.
回答by Amrish Pandey
You can trigger HeapDump using JMX bean HotSpotDiagnostic and second parameter of method set to false.
您可以使用 JMX bean HotSpotDiagnostic 和方法的第二个参数设置为 false 来触发 HeapDump。
See this answer for a more detailed response: https://stackoverflow.com/a/35575793/236528
有关更详细的回复,请参阅此答案:https: //stackoverflow.com/a/35575793/236528
回答by Sumit
Just remove live from the option and you should be good. When you're supplying "live" option to jmap. you're forcing JVM to run a Full GC and capture those supposed to be "live". use jmap -dump:format=b,file=hd.hprof rather.
只需从选项中删除 live 就可以了。当您为 jmap 提供“实时”选项时。您正在强迫 JVM 运行 Full GC 并捕获那些应该是“实时”的。而是使用 jmap -dump:format=b,file=hd.hprof。
回答by gabrielgiussi
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 7and Java 8have this option
-histo[:live]
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. The JVM internal class names are printed with an asterisk (*) prefix. If the live suboption is specified, then only active objects are counted.
-histo[:live]
打印堆的直方图。对于每个 Java 类,将打印对象数量、内存大小(以字节为单位)和完全限定的类名。JVM 内部类名打印有星号 (*) 前缀。如果指定了 live 子选项,则只计算活动对象。
-dump:[live,] format=b, file=filename
Dumps the Java heap in hprof binary format to 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.
-dump:[live,] 格式=b,文件=文件名
将 hprof 二进制格式的 Java 堆转储到文件名。live 子选项是可选的,但是当指定时,只会转储堆中的活动对象。要浏览堆转储,您可以使用 jhat(1) 命令读取生成的文件。
You could aldo use the jcmdcommand with the operation GC.heap_dump and the option -all
您也可以将jcmd命令与操作 GC.heap_dump 和选项 -all 一起使用
GC.heap_dump Generate a HPROF format dump of the Java heap. Impact: High: Depends on Java heap size and content. Request a full GC unless the '-all' option is specified.
GC.heap_dump 生成 Java 堆的 HPROF 格式转储。影响:高:取决于 Java 堆大小和内容。除非指定了“-all”选项,否则请求完整 GC。
Permission: java.lang.management.ManagementPermission(monitor)
权限:java.lang.management.ManagementPermission(monitor)
Syntax : GC.heap_dump [options]
语法:GC.heap_dump [选项]
Arguments: filename : Name of the dump file (STRING, no default value)
参数: filename :转储文件的名称(字符串,无默认值)
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.
For example, when I use jcmd without -all I see something like this.
您可以添加-XX:+PrintGCDetails
标志以查看是否正在发生 Full GC。例如,当我在没有 -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: [Full GC (Heap Dump Initiated GC) 200,658: [CMS: 5040K->4158K(18432K), 0,0171885 secs] 11239K->4158K(258555K30),->80K60K30,800K(18432K), 0,0171885 秒,0173941 秒] [时间:用户=0,01 系统=0,00,实际=0,02 秒]