简体   繁体   English

jmap活动堆转储如何包含无法访问的对象?

[英]How can a jmap live heap dump contain unreachable objects?

I used jmap to dump the live heap of an application using CMS GC: 我使用jmap使用CMS GC转储应用程序的活动堆:

jmap -dump:live,format=b,file=heap.hprof <pid>

I opened this dump with YourKit and it found that 61% of the 8Gb heap was unreachable, specifically 我使用YourKit打开了这个转储,发现8Gb堆的61%无法到达,特别是

Objects unreachable from GC roots, but not yet collected 126963949 5149290840 5149290840

I thought that using -dump:live meant that it would only contain reachable objects? 我以为使用-dump:live意味着它将仅包含可访问的对象?

The gc.log file for the application is suspiciously absent of any full GC caused by my invocation of jmap, and instead shows these lines either side of my taking the dump: 该应用程序的gc.log文件可疑地缺少我调用jmap导致的任何完整GC,而是在进行转储的两边显示了以下几行:

2019-07-17T09:32:59.808+0200: 33177.365: [GC (GCLocker Initiated GC) 2019-07-17T09:32:59.808+0200: 33177.365: [ParNew: 233127K->230550K(3397376K), 0.0265604 secs] 8029404K->8026859K(18496896K), 0.0267558 secs] [Times: user=0.92 sys=0.03, real=0.03 secs] 
2019-07-17T09:34:43.807+0200: 33281.363: [CMS-concurrent-preclean: 3.165/105.760 secs] [Times: user=143.74 sys=12.71, real=105.76 secs] 

In the first ParNew collection after the first CMS reset after the heap dump was taken, I see that the heap is roughly the size that was live in the heap dump (around 3-4Gb): 在执行了堆转储后的第一个CMS重置之后的第一个ParNew集合中,我看到堆的大小大约是堆转储中存在的大小(大约3-4Gb):

2019-07-17T09:34:55.850+0200: 33293.407: [GC (GCLocker Initiated GC) 2019-07-17T09:34:55.850+0200: 33293.407: [ParNew: 3264332K->260834K(3397376K), 0.0435628 secs] 6814726K->3811241K(18496896K), 0.0438372 secs] [Times: user=1.45 sys=0.04, real=0.05 secs] 

So maybe in this case jmap did not trigger a full GC? 因此,在这种情况下,jmap可能不会触发完整的GC? Is that possible/configurable? 那可能/可配置吗?

It does seem unexpected. 看来确实出乎意料。

You can try using jcmd <pid> GC.heap_dump filename=MyHeapdump 您可以尝试使用jcmd <pid> GC.heap_dump filename=MyHeapdump

It is the new recommended way to do a heap dump, and will force a Full GC by default. 这是推荐的新方法来执行堆转储,并且默认情况下将强制使用Full GC。 See oracle doc : 请参阅oracle doc

GC.heap_dump [options] [arguments] GC.heap_dump [选项] [参数]

Generates a HPROF format dump of the Java heap. 生成Java堆的HPROF格式转储。

Impact: High — depends on the Java heap size and content. 影响:高-取决于Java堆的大小和内容。 Request a full GC unless the -all option is specified. 除非指定-all选项,否则请求完整的GC。

There is this bug report from 2015 which states that the young generation is not being collected with -dump:live. 2015年有此错误报告,其中指出未使用-dump:live收集年轻一代。 I suppose this behaviour has not been changed. 我想这种行为没有改变。

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

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