Java 24将减少对象头大小并节省内存

将 HotSpot JVM 中的对象头大小从 96 到 128 位减少到 64 位架构上的 64 位。这将减少堆大小、提高部署密度并增加数据局部性。

目标 启用后,此功能

  • 必须在目标 64 位平台(x64 和 AArch64)上将对象头大小减小到 64 位(8 字节),
  • 应该减少实际工作负载下的对象大小和内存占用,
  • 不应在目标 64 位平台上引入超过 5% 的吞吐量或延迟开销,并且仅在极少数情况下才会出现,并且
  • 不应在非目标 64 位平台上引入可测量的吞吐量或延迟开销。

动机 存储在堆中的对象具有元数据,HotSpot JVM 将其存储在对象的标头中。标头的大小是恒定的;它与对象类型、数组形状和内容无关。在 64 位 HotSpot JVM 中,对象标头占用 96 位(12 字节)到 128 位(16 字节)之间的空间,具体取决于 JVM 的配置方式。

Java 程序中的对象通常较小。作为 Project Lilliput 的一部分进行的实验表明,许多工作负载的平均对象大小为 256 到 512 位(32 到 64 字节)。这意味着仅凭对象头就可以获取超过 20% 的实时数据。因此,即使对象头大小有一点改进,也可以显著减少占用空间、数据局部性并降低 GC 压力。Project Lilliput 的早期采用者已在实际应用中尝试过,证实实时数据通常会减少 10%–20%。 描述

压缩对象标头是一项实验性功能,因此默认情况下处于禁用状态。可以使用 启用压缩对象标头 -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders。

压缩类指针编码: 压缩类指针的当前实现仅限于大约 400 万个类。目前,用户可以通过禁用压缩类指针来解决此限制,但如果我们删除旧式标头实现,则将不再可能。我们通过提供紧凑的对象标头作为实验性功能来减轻当前的风险;从长远来看,我们打算努力实现更高效的压缩类指针编码方案。

实际情况 到目前为止,亚马逊的测试表明,许多工作负载的吞吐量实际上有所提高,有时甚至显著提高 - 有些工作负载的 CPU 利用率下降高达 30%

在合并到主分支之前,最近进行了一些测试。https ://wiki.openjdk.org/display/lilliput/Performance+Testing+for+JEP+450%3A+Compact+Object+Headers SpecJBB 是后端服务的合理演示,显示总体改进了 6%,主要是由于 GC 计数下降了 30%,CPU 缓存未命中率下降了 14-22%。对于代码透明的变化来说,这很神奇,而且很快 JVM 参数也会如此,但 30% 可能会产生误导。

无需等待 GA 版本。jdk.java.net上每周都会发布抢先体验版。

功能齐全的EA 版本在第一阶段的发布周发布,对于 JDK 24 来说,这个时间是 12 月 5 日。也就是说,功能齐全的 JDK 总是在 GA 发布前三个月可供测试。