gpt4 book ai didi

java - 如何解释实例的标记词?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:02:15 24 4
gpt4 key购买 nike

我正在尝试理解 Java object layout 的输出在 64 位 HotSpot VM (v8) 上。我不明白first three bit of the mark word怎么来的被使用,根据链接类文件中的注释,应该指示在实例上设置偏向锁或非偏向锁。

当我使用 JOL 分析 Object 的实例时

ClassLayout layout = ClassLayout.parseClass(Object.class);
Object object = new Object();
System.out.println(layout.toPrintable(object));

我得到以下输出:

java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (0000 0001 0000 0000 0000 0000 0000 0000)
4 4 (object header) 00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000)
8 4 (object header) e5 01 00 f8 (1110 0101 0000 0001 0000 0000 1111 1000)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes (estimated, add this JAR via -javaagent: to get accurate result)
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

来自 HotSpot's description of the mark word (前 8 个字节),我理解我应该将输出的上述位范围解释如下:

  • 00:01 - 锁定标志(示例中为 00。)
  • 02:02 - 偏向锁标志(示例中为 0。)
  • 03:06 - 年龄作为年轻垃圾收集迭代的次数。 (示例中为 0000。)
  • 07:07 - 未使用。 (似乎总是 1。)
  • 08:39 - 身份哈希码。 (仅在其计算之后,之前用零填充。)
  • 40:63 - 未使用。 (好像填满了零。)

确认哈希码范围的布局

至少对于哈希码,这可以通过计算身份哈希码并比较值来轻松确认:

ClassLayout layout = ClassLayout.parseClass(Object.class);
Object object = new Object();
// Check that the hash code is not set.
System.out.println(layout.toPrintable(object));

System.out.println("hash code: 0x" + Integer.toHexString(object.hashCode()));
// Confirm that the value is set:
System.out.println(layout.toPrintable(object));

// Compute the hash code manually:
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
long hashCode = 0;
for (long index = 7; index > 0; index--) {
hashCode |= (unsafe.getByte(object, index) & 0xFF) << ((index - 1) * 8);
}
System.out.println("hash code: 0x" + Long.toHexString(hashCode));

其中哈希码设置为实际位(忽略它仅由 31 位而不是 32 位表示的事实,因为提醒设置为零)。锁的标志都按预期设置为零。

验证偏向锁定的布局

markOops 还为对象何时受到偏向锁定提供了布局。在这里,最后两个要点替换为以下范围:

  • 08:09 - 纪元位
  • 10:63 - 持有此偏向锁的线程的指针。

当我现在尝试使用 -XX:BiasedLockingStartupDelay=0 运行以下代码的偏向锁时,我还可以观察偏向锁是如何设置的。当我运行以下代码时:

ClassLayout layout = ClassLayout.parseClass(Object.class);
Object object = new Object();

// Before using any lock, the layout is as above.
System.out.println(layout.toPrintable(object));

// When acquiring the lock, the thread ID can be seen as below:
synchronized (object) {
System.out.println(layout.toPrintable(object));
}

// After leaving the lock, the object is biased towards this thread:
System.out.println(layout.toPrintable(object));

偏向锁在初始加锁后的mark word中可见如下图:

java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 f0 3f 02 (0000 0101 1111 0000 0011 1111 0000 0010)
4 4 (object header) 00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000)
8 4 (object header) e5 01 00 f8 (1110 0101 0000 0001 0000 0000 1111 1000)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes (estimated, add this JAR via -javaagent: to get accurate result)
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

当我调用 object.hashCode() 时,我可以验证这不是代表哈希码,因为标记词发生变化(偏向锁被撤销)。

我不明白的是偏向锁和非偏向锁的标志仍然设置为零。 HotSpot 如何知道这是一个偏向锁而不是对象中表示的哈希码。我还想知道:epoch 位表示什么?

最佳答案

答案很简单:OpenJDK 的注释已经过时,而且今天的 mark word 组织方式不同。

关于java - 如何解释实例的标记词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27389585/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com