【问题标题】:How to check that java heap is fragmented?如何检查java堆是否碎片?
【发布时间】:2019-11-16 04:54:21
【问题描述】:

我有一个 29G 堆转储,由 Hotspot VM 在OutOfMemoryError 发生后创建。堆分析器(我使用 YourKit)显示所有对象(包括无法访问的对象)占用 26G。我的猜测是剩余的 3G 被浪费了,因为堆是碎片化的。有没有办法验证这个理论?

【问题讨论】:

标签: java jvm heap-dump fragmentation


【解决方案1】:

这与堆碎片无关。

大小的差异由堆转储格式解释。请注意,堆转储不是堆的原始内容 - 它是HPROF 格式的内容的序列化表示。

因此,每个对象实例都由以下结构的HPROF_GC_INSTANCE_DUMP 记录表示:

u1   record tag
u8   object ID                             
u4   stack trace serial number             
u8   class ID                       
u4   number of bytes that follow           
u1*  <field data>

考虑java.lang.Integer 的一个实例。在 64 位压缩 OOPs HotSpot JVM 中,Integer 的实例占用 16 个字节:8 字节标头 + 4 字节类指针 + 4 字节 value 字段。同一个实例将在堆转储中占用 29 个字节,从而产生 81.25% 的巨大开销。

当然,典型的 Java 应用程序中的堆通常充满了更大的对象,即数组。这就是为什么 HPROF 记录头的平均开销看起来更小,大约 10%,就像你的情况一样。

【讨论】:

  • 但是堆分析工具并没有显示对象在 hprof 文件中的占用情况,而是基本上猜测缺少的信息,如指针大小、对齐/填充等,当计算对象大小。所以问题确实是 hprof 格式,但不是表示对象的方式,而是缺少有关实际堆组织的信息。为了完整性:shipilev.net/blog/2014/heapdump-is-a-lie
猜你喜欢
  • 1970-01-01
  • 2010-09-14
  • 2019-01-06
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
  • 2010-10-15
相关资源
最近更新 更多