为什么 object header 大小在 64 位架构中翻了一番?

Why did object header size doubled in 64 bit architecture?

我真的不明白为什么 object header 在 64 位应用程序中变大两倍。 object header 是 8 个字节,在 64 位中是 16 这些额外的字节用于什么?

对象头由两个字段组成,syncblk 和方法 table 指针(又名 "type handle")。第二个字段很容易理解,它是一个指针,所以它 必须 在 64 位模式下从 4 字节增长到 8 字节。

syncblk 是不太明显的情况,它是标志和值(锁所有者线程 ID、哈希码、同步块索引)的混合体。没有理由在 64 位模式下让它变大。重要的是在 对象被 GC 收集后发生了什么。如果空闲 space 未通过压缩堆消除,则对象 space 参与空闲块列表。像双向链表一样工作。第二个字段是指向下一个空闲块的前向指针。对象数据 space 用于存储空闲块的大小,这是对象永远不会小于 12 字节的基本原因。并且 syncblk 存储指向前一个空闲块的后向指针。所以现在它必须足够大以存储指针,因此需要增长到 8 个字节。所以它是 8 + 8 = 16 个字节。

顺便说一下,64 位模式下的最小对象大小是 24 字节,即使 8 + 8 + 4 = 20 字节就可以了,只是为了确保所有内容都对齐到 8。对齐很重要,您永远不想让指针值跨越 L1 缓存行。使访问速度慢了大约 x3 倍。 <gcAllowVeryLargeObjects> 选项是另一个原因,稍后添加。