Java堆中的“live”对象是什么?(使用jmap进行堆转储)

6

jmap 帮助显示:

...

-dump:<dump-options> to dump java heap in hprof binary format
                    dump-options:
                      live         dump only live objects; if not specified,
                                   all objects in the heap are dumped.

...

当我转储一个带有Java参数-Xmx384m的Tomcat堆时:

jmap -dump:file=dump.bin <pid>

我得到了一个大约300兆的转储文件。

当我只使用活动的对象对其进行堆转储时:

jmap -dump:live,file=live-dump.bin <pid>

我得到了一个大约120M的dump文件。
我猜测活着的对象可能是:
1. 新生代中的对象; 2. 被使用/引用/可达且不会被回收的对象。
哪一个是正确的呢?
更新:
我的第二个猜测似乎是正确的,感谢Alexey Ragozin的解释(live选项将导致完整的GC)。根据他的提示,我进行了测试。
jmap -dump:file=dump.hprof <pid>
jmap -dump:live,file=live-dump.hprof <pid>
jmap -dump:file=after-live-dump.hprof <pid>

这三个文件的大小分别为:

dump.hprof ~190MB
live-dump.hprof ~40MB
after-live-dump.hprof ~40MB

所以,在使用 -dump:live 命令之后,堆中几乎所有的对象都是活动的。


@Holger 对不起,我的英语不好。#2 我的意思是那些尚未被回收但已经不再使用/引用的对象。 - auntyellow
抱歉,我的愚蠢错误 :-p - auntyellow
1个回答

15

jmap -dump:live,file=live-dump.bin <pid>

jmap命令中的live选项会强制JVM在将堆内容转储到文件之前执行一次完整的GC。

只有从GC根对象可达的对象(“活动对象”的定义)在堆中保留下来。


当您使用“live”选项时,JVM会执行完整的GC操作,这可能会导致应用程序完全挂起,有时需要很长时间,甚至对于使用大堆的应用程序可能无法完成。在这种情况下,如果您放弃“live”选项,则有很大机会完成堆转储。 - webjockey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接