Nan*_*ndo 18 java object padding
我知道Java使用填充; 对象必须是8个字节的倍数.但是,我没有看到它的目的.它是干什么用的?它的主要目的究竟是什么?
U2E*_*EF1 18
它的目的是对齐,允许以某些空间为代价更快地访问内存.如果数据未对齐,则处理器需要在加载内存后进行一些移位以访问它.
此外,垃圾收集简化(并加速),最小分配单元的大小.
Java不太可能需要8个字节(64位系统除外),但由于在创建Java时32位架构是常态,因此Java标准中可能需要4字节对齐.
接受的答案是推测(但部分正确).这是真正的答案.
首先,对于@ U2EF1而言,8字节边界的好处之一是8字节是大多数处理器上的最佳访问.但是,决定还有更多.
如果你有32位引用,你可以寻址最多2 ^ 32或4 GB的内存(实际上你会得到更少,更像是3.5 GB).如果你有64位引用,你可以寻址2 ^ 64,这是terrabytes的内存.但是,对于64位引用,一切都会变慢并占用更多空间.这是由于处理64位的32位处理器的开销,并且由于更少的空间和更多的垃圾收集,所有处理器上的GC周期更多.
因此,创建者采取了中间立场并决定使用35位引用,这允许最多2 ^ 35或32 GB的内存并占用更少的空间,因此具有32位引用的相同性能优势.这是通过采用32位参考并在读取时将其向左移位3位并在存储参考时将其右移3位来完成的.这意味着所有对象必须在2 ^ 3个边界(8个字节)上对齐.这些被称为压缩普通对象指针或压缩oops.
为什么不使用36位引用来访问64 GB内存?嗯,这是一个权衡.你需要大量的浪费空间来进行16字节对齐,据我所知,绝大多数处理器都没有从16字节对齐中获得速度优势,而不是8字节对齐.
请注意,除非最大内存设置为高于4 GB,否则JVM不会使用压缩oops,默认情况下不会.你可以用-XX:+UsedCompressedOops旗帜实际启用它们.
这是在32位虚拟机的当天,以便在64位系统上提供额外的可用内存.据我所知,64位虚拟机没有限制.
来源:Java性能:权威指南,第8章