为什么Java对象必须是8的倍数?

时间:2012-08-12 22:39:04

标签: java object padding

我知道Java使用填充;对象必须是8个字节的倍数。但是,我没有看到它的目的。它是干什么用的?它的主要目的究竟是什么?

3 个答案:

答案 0 :(得分:17)

其目的是alignment,它允许以某些空间为代价更快地访问内存。如果数据未对齐,则处理器需要在加载内存后进行一些移位以访问它。

此外,简化(并加速)垃圾收集的最小分配单元的大小。

Java不太可能需要8个字节(64位系统除外),但由于在创建Java时32位架构是常态,因此Java标准中可能需要4字节对齐。 / p>

答案 1 :(得分:8)

接受的答案是推测(但部分正确)。这是真正的答案。

首先,对于@ 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章

答案 2 :(得分:-1)

Java中的数据类型大小是8 (不是字节)的倍数,因为大多数现代处理器中的字大小是8位的倍数:16位,32位,64位。通过这种方式,可以使对象中的字段适应(“对齐”)一个或多个字,并尽可能少地浪费空间,利用底层处理器的指令来操作字大小的数据。