【问题标题】:GC roots in IBM java heapdump - is the list complete?GC 源于 IBM java heapdump - 列表是否完整?
【发布时间】:2018-04-09 05:40:58
【问题描述】:

我正在分析 IBM JVM 使用 Eclipse MAT 编写的 .phd 转储。

名为“gc_roots”的视图显示以下列表:

我可以确定 GC 根列表是完整的吗?
这是否意味着正在运行的线程堆栈中的所有局部变量都包含在“未知”部分中?

为什么它被命名为这样的BTW?

我对 GC 根列表完整性的怀疑是基于这样一个事实,即在抛出 OOM 时堆包含几个相当大的弱引用字符缓冲区。这看起来违反了合同,因为即使是 SoftReferences 也必须在 OOM 之前清除。

更新

这是同时编写的核心转储中的 GC 根列表,这让我更不清楚。

没有“未知”部分,而是出现了“JNI Global”。而且我仍然想知道堆栈中的局部变量在哪里。

【问题讨论】:

  • 这些缓冲区可能被引用它们的其他对象保持活动状态。 gc 根列表应该是完整的,除非 JVM 中存在重大错误。如果它完整,则意味着 JVM 泄漏内存,这当然不好。
  • 根据这两个转储,没有其他GC根路径,只有一个通过ThreadLocal,包含WeakReference。
  • 但是为什么你认为这里缺少一些 GC 根就意味着泄漏?
  • 当 OOME 被抛出时,您正在使用一些 JVM 选项来生成堆转储,对吧?否则对象的可达性可能会同时发生变化,例如因为堆栈是由 throw 展开的。
  • 是的,没错,转储是在 OOME 上自动生成的。

标签: java garbage-collection out-of-memory websphere gc-roots


【解决方案1】:

最后的收集不适用于某些 OOME 原因。例如,大于最大堆大小的分配尝试显然永远无法满足,并且任何集合都不会改变这一点。

您应该检查 OOME 的 message 属性。

我仍然想知道堆栈中的局部变量在哪里。

大概是Thread 类别。

【讨论】:

  • 消息只是“Java 堆空间”。但我不认为有任何意外的大分配请求。最大时,它可能与堆中的十几个缓冲区之一相同,应该相应地收集到转储中。
  • OOME 是否始终在某些特定的或一些相关的调用站点上抛出?还是在随机位置?
  • 随机位置,从未修复过。所以最后支持人员必须重新启动JVM。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
  • 2011-12-25
  • 2020-12-19
  • 1970-01-01
相关资源
最近更新 更多