java - Java OutOfMemoryError,但在 JFR 中看到的活动对象很少?
问题描述
我有一些代码会抛出OutOfMemoryError
.
我将 JVM 设置为在 OOM 上转储,然后在 Java Flight Recorder 中打开转储。
在 JFR 中检查活动对象时,我看到的对象很少(少于 60 个)。
在触发 OOM 时,如何找出内存中保存且不可收集的最大对象?
解决方案
由于所收集数据的性质,您不能以自动方式执行此操作(例如内存分析器工具使用堆转储执行此操作)。
您只能看到少数物体是完全可以的。原因是低开销采样的工作原理 - 在每个新的 TLAB 分配 JFR 介入并从旧 TLAB 中获取一些对象。因此,您不会记录所有对象,而只会分配具有代表性的对象样本。这应该足以为您提供堆中对象的比率。此外,报告的所有对象在记录转储时都是活动的。
如果您认为您获得的样本太少而无法得出正确的结论,则可能是您的堆相对于 TLAB 大小较小,您可能希望减小 TLAB 大小。这在生产环境中是不可取的,因为不正确的 TLAB 设置会降低应用程序性能。
如果您在记录期间在分析配置中设置了“内存泄漏检测”到“对象类型 + 分配堆栈跟踪 + GC 根路径”,则可以在创建后跟踪活动对象在代码中的位置,并且可以重建具有代表性的支配树方法。
如果您关心大对象本身就意味着大(并且不保留大部分堆),您可以通过查看“TLAB 分配”页面并查找“TLAB 外的总分配”列来找到大于 TLAB 的对象。仅当分析配置将“内存分析”设置为“对象分配和提升”时才会收集此数据。
settings
通过分析配置,我指的是您在开始使用 JFR 录制时使用选项指定的文件。该文件可以使用 JMC 应用程序的“飞行记录模板管理器”创建。
推荐阅读
- java - 没有任何关系的 LazyInitializationException - Spring Boot + Hibernate
- html - 如何使用引导程序在div中从左到中修复文本的位置
- android - 如何使用应用程序私有文件夹中的文件设置通知声音?
- firebase - Firebase:如果写入权限被拒绝,则阻止客户端回调执行
- java - 如何从另一个表中获取单个值作为字符串
- bash - 用上一行的内容替换文本
- android - 安卓 | 调试后手动安装apk失败
- ios - TableView 没有出现在我的容器中
- google-sheets - 使用 Google 表格从 URL 中提取数据
- angular - 从 hashmap 获取数据到 highcharts