为什么64位架构中的对象头大小翻了一番?

Dav*_*yan 5 .net c# clr garbage-collection memory-management

我无法理解为什么对象头在64位应用程序中变得更大.对象头是8个字节,64位是16这些额外的字节用于什么?

Han*_*ant 9

对象头由两个字段组成,syncblk和方法表指针(又名"类型句柄").第二个字段很容易理解,它是一个指针,因此它必须在64位模式下从4字节增长到8字节.

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

Fwiw,64位模式下的最小对象大小为24字节,即使8 + 8 + 4 = 20字节也可以,只是为了确保所有内容都与8对齐.对齐非常重要,你永远不会希望指针值跨越L1缓存行.使访问速度慢大约x3倍.该<gcAllowVeryLargeObjects>选项是另一个原因,稍后补充.