【问题标题】:How is a compressed ooP implemented in JVM?在 JVM 中如何实现压缩的 ooP?
【发布时间】: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

标签: java jvm


【解决方案1】:

http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#compressedOop

这是否回答了您的问题,它们是偏移量,它们用于索引 8 字节块而不是 1 字节块,因为对象是 8 字节对齐的。

【讨论】:

  • 一个非常愚蠢的问题:由于 32 位系统可以访问 2^32 个对象,即内存位置,而 32 位处理器的字长为 32 位 = 32 条数据线 = 4 字节,为什么RAM 限制为 2^32 * 8 位 = 4 GB 而不是 2^32 *32 位。是不是因为操作系统想要一次写入一个字节而不是一次写入 4 个字节(以防止由于对象对齐而造成内存浪费)?
  • 由于向后兼容,硬件可以在任何地方读取字节,但这样做效率非常低。
  • @MarkusMikkolainen 你对我在上述评论中的疑问说“是”吗?
  • 与操作系统无关,与intel架构和缓存等有关。
  • 哦,对了,所以我将重新提出我的问题:为什么 RAM 限制为 2^32 * 8 位 = 4 GB 而不是 2^32 *32 位。是不是因为处理器希望能够一次读取/写入一个字节,而不是一次读取 4 个字节(以防止由于对象对齐而导致内存浪费)
猜你喜欢
  • 2020-04-04
  • 2010-10-07
  • 2015-07-01
  • 1970-01-01
  • 2018-12-16
  • 2015-02-01
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
相关资源
最近更新 更多