【发布时间】:2015-09-01 17:30:24
【问题描述】:
快速的谷歌搜索结果令人惊讶。
我的问题如下:
对于 32 位架构 - 2^32 字节将是内存空间 = 4GB 所以对于 4 GB 的 Java 堆,我们需要一个大小为 32 位 = 4 字节的指针。
但是,通过压缩 oop 的概念,JVM 仍然可以使用 4 字节指针,最大堆大小为 32 GB。
仔细想想,32 GB = 4 GB * 2^3。 这意味着我们实际上还需要 3 位,但不知何故,这些位在存储/访问期间被 JVM 编码/解码。
我发现这些页面无法访问:http://wikis.sun.com/display/HotSpotInternals/CompressedOops https://wikis.oracle.com/display/HotSpotInternals/CompressedOops
谁能解释一下幕后发生的魔法?
致 Mods:我发现了一个现有问题,但它指向 https://wikis.oracle.com/display/HotSpotInternals/CompressedOops。这个 wiki 已经不存在了,请您允许这个问题这么久,以至于有人将我指向另一个深度链接。请。
编辑:
@Markus Mikkolainen 的回复是我找到的最简单的解释: 它们是偏移量,它们用于索引 8 字节块而不是 1 字节块,因为对象是 8 字节对齐的。
【问题讨论】:
-
在 Windows 32 位中,您只有 1.2 - 1.5 GB 的连续可用虚拟内存。在 Java 8 中,您可以使用 32 位引用来寻址高达 64 GB 的堆。它将对象对齐从 8 个字节增加到 16 个字节。
-
如果我是正确的,这是否意味着 Java 对象在堆上的最小大小为 16 字节? (因为从第 9 个字节开始的对象无法在内存中表示?)
-
我会说一个对象将使用的最小空间是 16 个字节,包括标题和对象对齐。如果您使用
-XX:-UseTLAB关闭 TLAB,您可以看到每个对象分配的确切空间量。 -
正确,您需要 32 GB