java - jmap 实时堆转储如何包含无法访问的对象?
问题描述
我使用 jmap 转储使用 CMS GC 的应用程序的实时堆:
jmap -dump:live,format=b,file=heap.hprof <pid>
我用 YourKit 打开了这个转储,发现 61% 的 8Gb 堆无法访问,特别是
Objects unreachable from GC roots, but not yet collected 126963949 5149290840 5149290840
我认为 using-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?那可能/可配置吗?
解决方案
这似乎出乎意料。
您可以尝试使用jcmd <pid> GC.heap_dump filename=MyHeapdump
这是进行堆转储的新推荐方法,默认情况下会强制进行 Full GC。请参阅oracle 文档:
GC.heap_dump [选项] [参数]
生成 Java 堆的 HPROF 格式转储。
影响:高 — 取决于 Java 堆大小和内容。除非指定了 -all 选项,否则请求完整的 GC。
推荐阅读
- bash - 如何仅获取 bash ssh 版本号?
- javascript - 如何将数据从 api 推送到数据集中
- react-native - 如何使 createMaterialTopTabNavigator tabBar 背景颜色为线性渐变
- flutter - 如何在颤振中使用 Navigator.pop() 方法传递多个值?
- javascript - 如何在 Visual Studio 中以所有形式更新 javascript 文件的版本
- c# - 从 Chocolatey 生成的 exe 有他们的 Logo 和描述。有没有办法改变这个?
- amazon-web-services - 每日数据加载的 AWS API Gateway POST 请求
- swift - 复制 iPhone 故事板并直接粘贴到 iPad 故事板上,但并非每个视图控制器都能在 iPad 上正确显示
- javascript - onOpen 状态“失败”是什么意思?
- javascript - 来自类的 JSPDF 自动表格自定义样式