jol GraphLayout 输出中的“(其他)”是啥?

Posted

技术标签:

【中文标题】jol GraphLayout 输出中的“(其他)”是啥?【英文标题】:What is "(something else)" in jol GraphLayout output?jol GraphLayout 输出中的“(其他)”是什么? 【发布时间】:2015-07-13 07:19:37 【问题描述】:

当使用 jol 的 GraphLayout 类打印从对象实例引用的对象图时,一些输出条目会显示“(其他)”而不是类型和引用路径。例如,考虑以下代码,它打印 20 个随机 Integer 对象的列表图:

List<Integer> foo = new Random().ints(20).boxed().collect(Collectors.toList());
System.out.println(GraphLayout.parseInstance(foo).toPrintable());

此代码打印:

java.util.ArrayList object externals:
          ADDRESS       SIZE TYPE                PATH                           VALUE
         d642ecc8         24 java.util.ArrayList                                (object)
         d642ece0         16 java.lang.Integer   .elementData[0]                212716192
         d642ecf0         56 (something else)    (somewhere else)               (something else)
         d642ed28         16 java.lang.Integer   .elementData[1]                1503736768
         d642ed38         16 java.lang.Integer   .elementData[2]                -2099759732
         d642ed48         16 java.lang.Integer   .elementData[3]                445566433
         d642ed58         16 java.lang.Integer   .elementData[4]                -1528625708
         d642ed68         16 java.lang.Integer   .elementData[5]                -555424299
         d642ed78         16 java.lang.Integer   .elementData[6]                1607595284
         d642ed88         16 java.lang.Integer   .elementData[7]                763466772
         d642ed98         16 java.lang.Integer   .elementData[8]                638331919
         d642eda8         16 java.lang.Integer   .elementData[9]                -1742026575
         d642edb8         16 java.lang.Integer   .elementData[10]               1920101909
         d642edc8         80 (something else)    (somewhere else)               (something else)
         d642ee18         16 java.lang.Integer   .elementData[11]               2001035318
         d642ee28         16 java.lang.Integer   .elementData[12]               -1920666937
         d642ee38         16 java.lang.Integer   .elementData[13]               -991335829
         d642ee48         16 java.lang.Integer   .elementData[14]               -47760298
         d642ee58         16 java.lang.Integer   .elementData[15]               855824902
         d642ee68        104 [Ljava.lang.Object; .elementData                   [212716192, 1503736768, -2099759732, 445566433, -1528625708, -555424299, 1607595284, 763466772, 638331919, -1742026575, 1920101909, 2001035318, -1920666937, -991335829, -47760298, 855824902, 2137884845, -226328690, 1472718384, 890105604, null, null]
         d642eed0         16 java.lang.Integer   .elementData[16]               2137884845
         d642eee0         16 java.lang.Integer   .elementData[17]               -226328690
         d642eef0         16 java.lang.Integer   .elementData[18]               1472718384
         d642ef00         16 java.lang.Integer   .elementData[19]               890105604

在 DuckDuckGo 和 Google 上搜索 jol "something else" 没有返回任何有用的匹配结果。

“(其他)”条目代表什么?

【问题讨论】:

【参考方案1】:

"(something else)" 的意思就是——不是这个对象图的一部分。那里可能有其他(活动的或垃圾)对象,或者由于某些 VM 内部原因而在堆中存在一个间隙。

请注意,图中的对象表是按地址排序的。 ArrayList 的elementData 数组在添加第一个元素时被延迟初始化,当向列表中添加第十个元素时,elementData 被重新分配以腾出空间容纳更多元素。这会在对应于(现在是垃圾)数组的堆区域中创建间隙,并且 jol 将它们打印为“(其他)”条目。负责打印这些条目的代码是 GraphLayout line 246(至少在此发布时)。

jol 打印有关堆间隙的这些信息,以帮助理解垃圾收集器的行为。后来的一些jol examples 证明了这一点,例如compaction example,它显示了从 ArrayList 引用的对象最初是稀疏的,但被垃圾收集器压缩。

【讨论】:

我喜欢人们自行回答问题 :) 不过,我不确定“其他东西”是否是一个好概念:它似乎一次又一次地绊倒人们。但是,我找不到更好的(简短的)描述。

以上是关于jol GraphLayout 输出中的“(其他)”是啥?的主要内容,如果未能解决你的问题,请参考以下文章

格式化Java内存工具JOL输出

利用sun.misc.Unsafe获取类字段的偏移地址和读取字段的值

jol在Java9下是否有点破?

使用JOL工具计算Java对象的大小

java对象布局(JOL)

java对象的内存布局:利用sun.misc.Unsafe获取类字段的偏移地址和读取字段的值