我使用jmap使用CMS GC转储应用程序的活动堆:
jmap -dump:live,format=b,file=heap.hprof <pid>
我用YourKit打开了这个转储,它发现8Gb堆中有61%是无法到达的,
Objects unreachable from GC roots, but not yet collected 126963949 5149290840 5149290840
我认为使用-dump:live
意味着它仅包含可到达的对象?
该应用程序的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]
在执行了堆转储后的第一个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]
那么也许在这种情况下jmap没有触发完整的GC?这可能/可配置吗?
答案 0 :(得分:0)
这似乎是意外的。
您可以尝试使用jcmd <pid> GC.heap_dump filename=MyHeapdump
这是建议的执行堆转储的新方法,默认情况下将强制使用Full GC。 参见oracle doc:
GC.heap_dump [选项] [参数]
生成Java堆的HPROF格式转储。
影响:高-取决于Java堆的大小和内容。除非指定-all选项,否则请求完整的GC。
答案 1 :(得分:0)
有一个bug report from 2015,它表示未使用-dump:live收集年轻一代。我想这种行为没有改变。