写点什么

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

作者:Ben Evans

  • 2024-12-13
    北京
  • 本文字数:1756 字

    阅读完需:约 6 分钟

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

JEP450(Compact Object Headers,紧凑对象头)已经成为 JDK 24 的交付目标,并且已合并到了主版本中。


这个目前处于实验阶段的特性通过缩小 HotSpot 中强制对象头的大小来优化堆利用率。这应该会减少整体堆的大小,提高部署密度,并增加数据局部性。


当前的实现情况概述


HotSpot 将所有对象存储在 Java 堆中,Java 堆是进程的“C 堆”的连续区域。在 Java 中始终是通过引用来处理对象,例如:


  1. 引用对象的局部变量包含从 Java 方法的堆栈帧到 Java 堆的指针。

  2. 引用类型的对象字段从一个 Java 堆位置指向另一个位置。


Java 引用的目标地址始终是对象头的开始处(这在当前版本的 HotSpot 中是强制性的)。


每个对象上都有标头(数组还有一个额外的 32 位标头来存储数组的长度)。标记字是前 64 位,用于特定于实例的元数据,即支持以下特性:


  • 垃圾回收——存储对象的年龄(以及可能的转发指针)

  • 哈希码——存储对象的稳定身份哈希码

  • 锁——存储对象的锁 / 监视器


在某些情况下,标记字将被覆盖并被替换为指向更复杂数据结构的指针。这会使紧凑对象头的实现稍微复杂一些。


在标记字之后是类(或 klass)字,用于计算指向此类类型的每个对象所共享的元数据的指针。这用于方法调用、反射、类型检查等。


klass 元数据(或 klass)保存在元空间中,元空间位于 Java 堆之外,但在 JVM 进程的 C 堆之内。由于它们存在于 Java 堆外,因此 klass 不需要 Java 对象头,而且它们与反射中使用的类对象(真正的 Java 对象)不同。


klass 字最初是标头的一个完整机器字,但这在 64 位的架构上是很浪费的,因此引入了一种称为“压缩类指针”的技术。这将类指针编码为 32 位(通过使用缩放和偏移方法),适用于加载小于 4GB 类文件的任何应用程序。


因此,除了极端情况外,64 位版本的 HotSpot 上的非数组对象要支付 96 位的“标头税”。相比之下,这是轻量级的:直到最近,Python 的标头税还是 308 字节,但 JEP 450 的目的是为了做得更好,将标头的总大小减少到 64 位。


引入紧凑对象头


这个新实现是作为 OpenJDK 的“Project Lilliput”的一部分开发的,它减少了两个目标 64 位平台(x64 和 AArch64)上的对象头大小。


总体目标是:


  • 将目标平台上的吞吐量和延迟开销限制在 5% 内,并且只有在极少数情况下才能达到这一限制

  • 不会在非目标平台上引入可测量到的吞吐量或延迟开销


事实上,目前的测试只显示了极少数的回归(JDK 24 正在对它们进行修复)。到目前为止,亚马逊(Amazon)的测试表明,许多工作负载实际上在吞吐量方面受益,有时甚至会有大幅提升——一些工作负载的 CPU 利用率下降了 30%。


该项目试图利用观察到的事实,即许多 Java 工作负载的平均对象大小较小,只有 32 到 64 字节。这相当于约 20% 的标头税。因此,即使对象头大小略有改进,也可以显著减少堆的占用空间。反过来,这可以提高数据局部性并减少 GC 压力,从而带来进一步的潜在性能优势。


为了实现这种标头的减小,标记字和类字被组合成一个 64 位字,布局如下:



我们应该注意到以下几个方面:


  1. 现在有 22 位(而不是 32 位)用于标识对象类类型。这意味着我们可以加载到 JVM 进程中的不同类类型的数量约为 400 万个。

  2. 哈希码的大小不会变。

  3. 锁定操作不再覆盖标记字。这将保留压缩的类指针。

  4. 为了保持对压缩类指针的直接访问,GC 转发操作变得更加复杂。

  5. 有 4 个未使用的位保留用于未来的增强(例如 Valhalla 项目)


如果 Java 锁存在争用,那么新的实现需要查找保存锁信息的 辅助数据结 构的地址。这种方法称为“对象监视表”,已经在 JDK 22 中实现了,并由默认启用的新开关 UseObjectMonitorTable 激活。紧凑对象头依赖于此机制。


如果没有发现任何阻碍问题,这一特性将作为 JDK 24 的一部分发布(最初是一个实验特性),发布时间预计在 2025 年 3 月。长期的目标是使该机制成为受支持平台上唯一的标头表示,但这可能需要更多的版本。它还取决于对实际工作负载的广泛测试,目前缺乏性能和其他回归。甚至还有正在进行的探索性工作,以查看是否有可能将标头大小减小到 32 位。


一旦该特性在 JDK 24(测试版或最终版)中可用,应用程序团队可以通过命令行开关 -XX:UseCompactObjectHeaders 来激活该新特性以测试他们的工作负载,并寻找与之相关的性能差异,从而为长期目标提供帮助。


原文链接:

https://www.infoq.com/news/2024/11/compact-headers-java24/

2024-12-13 08:008717

评论

发布
暂无评论
发现更多内容

面向CV编程:COPY了别人文章中的代码,想让代码能像作者一样跑通,应该注意什么呢?怎样才能让代码愉快地跑起来呢

迷彩

读书笔记 高效工作 程序员 个人思考 5月月更

当你运行npm run命令时,会发生什么

华为云开发者联盟

JavaScript typescript npm Script run命令

银行借助纵向联邦学习 集中化进行长尾客群的精准营销

易观分析

联邦学习 联邦计算

做不好资产清点的网络安全防护都是耍流氓!

青藤云安全

青藤参与编写的《数据安全法》实施参考(第一版)发布

青藤云安全

即时通讯安全篇(九):为什么要用HTTPS?深入浅出,探密短连接的安全性

JackJiang

https 即时通讯 ssl im开发

druid 源码阅读(四)返回一个连接

爱晒太阳的大白

5月月更

如何使用Python实现图像融合及加法运算

华为云开发者联盟

Python OpenCV 图像处理 图像融合 加法运算

引领创新!青藤入选“网信自主创新尖锋企业”

青藤云安全

企评家 | 每日互动股份有限公司成长性评价简介

企评家

如何设计产品帮助中心?从这几点出发

小炮

不用PyScript,网页端运行的Python编辑器

OpenHacker

Python 编辑器 代码编辑器

满足多用途和峰值性能需求,英特尔 Arctic Sound-M成就出色游戏串流体验

科技新消息

基于STM32+华为云IOT设计智能称重系统

华为云开发者联盟

物联网 传感器 stm32 华为云IoT平台 智能称重系统

Node.js可以用来做什么事?

小学僧

node.js 前端 5月月更

【愚公系列】2022年05月 二十三种设计模式(十三)-职责链模式(Chain of Responsibility Pattern)

愚公搬代码

5月月更

最「难搞」的英伟达也开源了,苹果会是下一个吗?

腾源会

开源 英伟达 苹果 腾源会

青藤正式加入微软MAPP计划

青藤云安全

西门子PLC设备如何接入AIRIOT物联网低代码平台 ?

AIRIOT

物联网, PLC 低代码开发 低代码平台

全新升级!阿里巴巴2022最新Spring源码全家桶全彩笔记开源

Java全栈架构师

spring 源码 程序员 面试 程序人生

不用PyScript,网页端运行的Python编辑器

Alexads

Python 代码编辑器

干货| 四种渲染到底是啥?终于有人讲明白了!(上)

Orillusion

开源 WebGL 元宇宙 Metaverse webgpu

druid源码学习四-多线程之锁探究

Nick

Apache Druid 锁机制 多线程安全

2年,0事故,效能提升10倍的云原生安全最佳实践

青藤云安全

金融行业 金融服务安全 青藤

福昕软件与神州数码达成中国区分销合作

联营汇聚

周日直播,龙蜥社区等8位专家在线报告 | 2022大学生操作系统大赛培训会

OpenAnolis小助手

操作系统 人才培养 大学生 龙蜥社区

技术创新!青藤威胁检测论文入选国家中文核心期刊

青藤云安全

论文 威胁检测

一文简述:容灾等级&保护程度

穿过生命散发芬芳

容灾 5月月更

企评家,为沪深主板企业成长性评价

企评家

Maven 项目

Emperor_LawD

maven 5月月更

Collections和Objects的使用注意

zarmnosaj

5月月更

Java 24减少对象头的大小并节省内存_编程语言_InfoQ精选文章