java - jmap 实时堆转储如何包含无法访问的对象?

标签 java heap-dump concurrent-mark-sweep

我使用 jmap 转储使用 CMS GC 的应用程序的 Activity 堆:

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

我用 YourKit 打开这个转储,它发现 61% 的 8Gb 堆是不可访问的,特别是

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 集合中,我看到堆的大小大致与堆转储中的 Activity 大小相同(大约 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?这可能/可配置吗?

最佳答案

这确实出乎意料。

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

这是进行堆转储的新推荐方法,默认情况下会强制执行 Full GC。 参见 oracle doc :

GC.heap_dump [options] [arguments]

Generates a HPROF format dump of the Java heap.

Impact: High — depends on the Java heap size and content. Request a full GC unless the -all option is specified.

关于java - jmap 实时堆转储如何包含无法访问的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57076435/

相关文章:

java - 如何在Java中从xml文件中提取大量字符

eclipse - 打开堆转储时出错

Java CMS GC,系统空闲时GC线程占用CPU

java - 我的循环仅检查第一个数组项

java - 如何使用数据库中的值制作记事本文档

java - 我可以将 MongoDB 用于 ActiveMQ 主/从架构吗?

java - 当 K8s 健康检查重新启动 pod 时创建 JVM heapdump - 没有发生 OOM

java - 增加 jvisualVM OQL 结果集的最大大小

java - -XX :+UseConcMarkSweepGC (what is default young generation collector? )