JDK 24:Java 24 中的新功能
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:历代文学,移动端可微信小程序搜索“历代文学”)总架构师,
15年
工作经验,精通Java编程
,高并发设计
,Springboot和微服务
,熟悉Linux
,ESXI虚拟化
以及云原生Docker和K8s
,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
技术合作请加本人wx(注明来自csdn):foreast_sea
为下一个版本的 Java 提出了 21 项功能,包括旨在保护 Java 应用程序免受未来量子计算攻击的抗量子加密密钥。
继 9 月 17 日发布的 Java 开发工具包 (JDK) 23 之后,现在的工作重点是计划的后续版本 JDK 24,该版本已膨胀到 21 个提议的功能。最近添加的两个提案将通过提供抗量子模块网格的数字签名算法和抗量子模块网格的密钥封装机制的 Java 实现,提高 Java 对量子计算攻击的抵抗力。
以前提议的功能包括删除 32 位 x86 端口;同步虚拟线程而不固定;简单的源文件和实例 main 方法;永久禁用安全管理器;模块导入声明;Compact Headers 的实验版本;patterns、instanceof 和 switch 中的基元类型;链接没有 JMOD 的运行时映像;世代相传的 Shenandoah 垃圾收集器;范围值;密钥派生函数 API;删除了 Z Garbage Collector 中的非分代模式;溪流收集器;一个矢量 API;类文件 API;警告,让开发人员为将来对 JNI (Java Native Interface) 的使用限制做好准备;以及 G1 垃圾回收器的后期屏障扩展。
JDK 24 优于 JDK 23,后者列出了 12 个官方功能
JDK 24 已指定为非长期支持 (LTS) 版本,截止日期为 2025 年 3 月 18 日。与 JDK 23 一样,JDK 24 将仅获得 Oracle 提供的六个月高级支持。JDK 24 的抢先体验版本可以在 jdk.java.net 上找到。
为通过抗量子性提高 Java 安全性而提出的两个功能包括抗量子模块晶格的密钥封装机制 (ML-KEM) 和抗量子量子晶格的基于数字签名算法 (ML-DSA)。ML-DSA 将使用数字签名来检测对数据的未经授权的修改并验证签名者的身份,从而抵御未来的量子计算攻击。密钥封装机制 (KEM) 用于使用公钥加密技术在不安全的通信通道上保护对称密钥。这两项功能都旨在防范未来的量子计算攻击。
灵活的构造函数主体在 JDK 22 和 JDK 23 中出现后,现在处于第三个预览阶段,尽管在 JDK 22 中具有不同的名称,当时该功能在 super(...) 之前称为 statements。该功能旨在重新构想构造函数在对象初始化过程中的角色,让开发人员更自然地将他们当前必须考虑的逻辑放入辅助静态方法、辅助中间构造函数或构造函数参数中。
Ahead-of-time class loading and linking 旨在通过在 HotSpot Java 虚拟机启动时使应用程序的类立即处于加载和链接状态来缩短启动时间。这将通过在一次运行期间监视应用程序并将所有类的加载和链接形式存储在缓存中以供后续运行使用来实现。
Windows 32 位 x86 端口在 JDK 21 中已弃用,无法删除,并打算在未来发行版中删除它。计划要求删除源代码并构建对 Windows 32 位 x86 端口的支持。目标包括删除仅适用于 Windows 32 位 x86 的所有代码路径,停止所有针对 Windows 32 位 x86 平台的测试和开发工作,以及简化 JDK 的构建和测试基础结构。该提案指出,Windows 10 是最后一个支持 32 位操作的 Windows 操作系统,将于 2025 年 10 月结束其生命周期。
同步虚拟线程而不固定涉及提高使用同步方法和语句的 Java 代码的可伸缩性,方法是安排在此类构造中阻塞的虚拟线程释放其底层平台供其他线程使用。这将消除几乎所有虚拟线程被固定到平台线程的情况,这严重限制了可用于处理应用程序工作负载的虚拟线程的数量。
简单源文件和实例 main 方法的第四个预览版将发展 Java 语言,因此初学者可以编写他们的第一个程序,而无需了解为大型程序设计的语言功能。该功能之前在 JDK 21、JDK 22 和 JDK 23 中预览过。目标是允许初级 Java 程序员为单类程序编写简化的声明,然后随着技能的增长无缝扩展他们的程序以使用更高级的功能。
永久禁用安全管理器涉及修改 Java 平台规范,以便开发人员无法启用安全管理器,而其他平台类则不引用它。该提案指出,多年来,安全管理器一直不是保护客户端 Java 代码的主要手段,很少用于保护服务器端代码,并且维护成本高昂。安全管理器在 Java 17 中已被弃用,无法删除。
之前在 JDK 23 中预览的模块导入声明增强了 Java 编程语言,使其能够简洁地导入模块导出的所有包。这简化了模块化库的重用,但不需要将代码导入为模块本身。
紧凑对象标头会将 HotSpot VM 中的对象标头大小从 96 到 128 位减少到 64 位架构上的 64 位。所提议的功能的目标是减小堆大小、提高部署密度和增加数据局部性。
JDK 24 中 patterns、instanceof 和 switch 中的基元类型的第二个预览版将允许所有模式和上下文中的基元类型,从而增强模式匹配。该功能还将扩展并适用于所有原始类型。该功能的目标包括通过允许所有类型的类型模式(无论是原始类型还是引用类型)来实现统一的数据探索;使类型与安全铸造对齐;并允许模式匹配在嵌套和顶级模式上下文中使用原始类型。此功能之前在 JDK 23 中预览过。instanceof
switch
instanceof
instanceof
其他目标包括提供易于使用的结构,以消除由于不安全的强制转换而丢失信息的风险,遵循 Java 5 和 Java 7 中的增强功能,并允许处理任何原始类型的值。switch
switch
通过链接没有 JMOD 的运行时映像,计划通过启用 jlink 工具创建没有 JDK JMOD 文件的自定义运行时映像,将 JDK 的大小减少大约 25%。默认情况下,此功能必须启用,某些 JDK 供应商可能会选择不启用此功能。目标包括允许用户从模块链接运行时映像,无论这些模块是独立的 JMOD 文件、模块化 JAR 文件还是以前链接的运行时映像的一部分。推动此提案的理念是,文件系统上安装的 JDK 大小在云环境中非常重要,在云环境中,包含已安装 JDK 的容器镜像会通过网络自动且频繁地从容器注册表复制。减小 JDK 的大小将提高这些操作的效率。
分代 Shenandoah 将通过实验性的分代收集功能来增强垃圾回收器,以提高可持续吞吐量、负载峰值抵抗力和内存利用率。主要目标是提供一种实验性的代际模式,而不打破非代际的 Shenandoah。分代模式旨在成为未来发行版中的默认模式。
作用域值使方法能够与线程中的被调用方和子线程共享不可变数据。作用域值比本地线程变量更容易推理。它们还具有较低的空间和时间成本,尤其是在与虚拟线程和结构化并发一起使用时。范围值 API 提议在 JDK 20 中孵化,提议在 JDK 21 中预览,并针对 JDK 22 和 JDK 23 进行了改进和完善。范围值将在 JDK 24 中预览。
使用密钥派生函数 (KDF) API,将为密钥派生函数引入 API,密钥派生函数是用于从密钥和其他数据派生其他密钥的加密算法。此提案的目标是允许安全提供商在 Java 代码或本机代码中实现 KDF 算法。另一个目标是使应用程序能够使用 KDF 算法,例如基于 HMAC(哈希消息身份验证代码)的提取和扩展密钥派生函数 (RFC 5869) 和 Argon2 (RFC 9106)。
删除 Z Garbage Collector (ZGC) 的非分代模式是一项旨在降低支持两种不同模式的维护成本的提案。该提案指出,维护非分代 ZGC 会减慢新功能的开发速度,对于大多数用例,分代 ZGC 应该是比非分代 ZGC 更好的解决方案。后者最终应替换为前者,以降低长期维护成本。该计划要求通过废弃 ZGenerational 选项并删除非分代 ZGC 代码及其测试来删除非分代模式。非分代模式将在将来的发行版中过期,此时 HotSpot JVM 将无法识别它,从而拒绝启动。
流收集器将增强流 API 以支持自定义中间操作。流收集器允许流管道以现有内置中间操作不容易实现的方式转换数据。此功能在 JDK 22 和 JDK 23 中作为预览版提出。API 将在 JDK 24 中完成。目标包括使流管道更加灵活和富有表现力,并允许自定义中间操作来操作无限大小的流。
矢量 API 旨在表达矢量通信,这些通信在运行时可靠地编译为受支持的 CPU 架构上的最佳矢量指令,从而实现优于等效标量计算的性能。vector API 以前是在 JDK 16 到 JDK 23 中孵化的。它将在 JDK 24 中重新孵化,与 JDK 23 相比,没有 API 更改,也没有实质性的实现。该提案的目标包括在与平台无关的 API 中清晰简洁地表达各种向量计算,在 x64 和 AArch54 架构上提供可靠的运行时编译和性能,当向量计算无法在运行时表达时优雅地降级并仍然起作用,以及与 Valhalla 项目保持一致,利用 Java 对象模型的增强功能。
以前在 JDK 22 和 JDK 23 中预览的类文件 API 将在 JDK 24 中完成,但会稍作更改。此 API 提供用于解析、生成和转换 Java 类文件的标准 API。它旨在提供一个 API 来处理类文件,该 API 跟踪 Java 虚拟机规范定义的类文件格式。第二个目标是使 JDK 组件能够迁移到标准 API,并最终删除第三方 ASM 库的 JDK 内部副本。自第二次预览以来的更改包括重命名枚举值、删除某些字段、添加方法和方法重载、重命名方法以及删除被视为不必要的接口和方法。
G1 垃圾回收器的后期 barrier 扩展旨在简化 G1 的 barrier 的实现。G1 垃圾回收器的屏障通过将它们的扩展从 C2 编译管道的早期转移到后期来记录有关应用程序内存访问的信息。目标包括减少使用 G1 收集器时 C2 编译的执行时间,使对 C2 缺乏深入了解的 HotSpot 开发人员能够理解 G1 屏障,并保证 C2 保留有关内存访问、安全点和屏障的相对顺序的不变量。第四个功能是保持 C2 生成的 JIT(即时)编译代码的速度和大小。
第一个面向 JDK 24 的功能,正式名称为“准备限制 JNI 的使用”,要求发出有关 JNI 使用的警告,并调整 JDK 22 中的外部函数和内存 (FFM) API,以一致的方式发出警告。这些警告旨在为未来版本做准备,该版本通过统一限制 JNI 和 FFM API 来确保默认情况下的完整性。该计划的目标包括保留 JNI 作为与本机代码互操作的标准方式,为默认情况下不允许与本机代码互操作的未来版本准备 Java 生态系统,以及协调 JNI 和 FFM API 的使用,以便库维护者可以从一个迁移到另一个,而无需开发人员更改命令行选项。
针对 JDK 24 的其他功能将在接下来的几周内确定。其他可能的 Java 24 功能包括结构化并发(可简化并发编程)和字符串模板(在 JDK 21 和 JDK 22 中预览,但在 JDK 23 中删除了该功能)。
最新的 LTS 版本 JDK 21 于 2023 年 9 月发布,预计将从 Oracle 获得至少五年的标准支持。下一个 LTS 版本 JDK 25 将于 2025 年 9 月发布。LTS 版本在 Java 采用中占据主导地位,这意味着随着用户等待 JDK 25,JDK 23 和 JDK 24 的采用率可能处于低端。
Java 24 减小对象标头大小并节省内存
JEP 450(Compact Object Headers)已计划在 JDK 24 中交付,并且已经合并到 main。
这个目前的实验性功能通过缩小 HotSpot 中强制对象头的大小来优化堆利用率。这应该会减小总体堆大小,提高部署密度,并增加数据局部性。
当前实施概述
HotSpot 将所有对象存储在 Java 堆中,Java 堆是进程的 “C heap” 的连续区域。Java 中的对象始终通过引用处理,例如:
- 引用对象的局部变量包含从 Java 方法的堆栈帧到 Java 堆的指针。
- 引用类型的对象字段从一个 Java 堆位置指向另一个 Java 堆位置。
Java 引用的目标地址始终是对象头的开头(这在当前版本的 HotSpot 中是必需的)。
每个对象上都存在 Headers(数组有一个额外的 32 位 Headers 来存储数组的长度)。标记字是前 64 位,用于特定于实例的元数据,即支持以下功能:
- 垃圾收集 - 存储对象的年龄(可能还有转发指针)
- 哈希代码 - 存储对象的稳定身份哈希代码
- Locks - 存储对象的锁 / 监视器
在某些情况下,标记字将被覆盖并替换为引用更复杂数据结构的指针。这使得紧凑对象标头的实现稍微复杂一些。
标记字后面是类(或 klass)字,该字用于计算指向此类类型的每个对象共享的元数据的指针。这用于方法调用、反射、类型检查等。
klass 元数据(或 klass)保存在元空间中,元空间位于 Java 堆之外,但不在 JVM 进程的 C 堆之外。由于它们存在于 Java 堆之外,因此 klasses 不需要 Java 对象头,并且它们与反射中使用的类对象(它们是真正的 Java 对象)不是一回事。
klass 字最初是 header 的全机器字,但这在 64 位架构上是浪费的,因此引入了一种称为“压缩类指针”的技术。这会将类指针编码为 32 位(通过使用缩放和偏移方法),这适用于加载少于 4 GB 的类文件的任何应用程序。
因此,除了边缘情况外,64 位版本的 HotSpot 上的非数组对象还支付了 96 位的“头税”。相比之下,这是轻量级的:直到最近,Python 的头税是 308 字节,但 JEP 450 的目的是做得更好,并将头的总大小减少到 64 位。
Compact Object Headers 简介
新实现是作为 OpenJDK 的“Project Lilliput”的一部分开发的,它减小了两个目标 64 位平台(x64 和 AArch64)上的对象头大小。
总体目标是:
- 在目标平台上将吞吐量和延迟开销限制为 5%,并且仅在不常见的情况下接近该限制
- 不会在非目标平台上引入可测量的吞吐量或延迟开销
事实上,测试目前只显示了极少数的回归(JDK 24 正在进行一些修复)。到目前为止,Amazon 的测试表明,许多工作负载实际上在吞吐量方面受益匪浅,有时甚至非常明显 - 某些工作负载的 CPU 利用率下降了高达 30%。
该项目试图利用观察到的事实,即许多 Java 工作负载的平均对象大小很小,为 32 到 64 字节。这相当于 ~20% 的头税。因此,即使对象头大小略有改进,也可以显著减少堆占用空间。反过来,这可以提高数据局部性并降低 GC 压力,从而进一步获得潜在的性能优势。
为了实现这种 Headers 缩减,mark 和 class 字被组合成一个 64 位字,布局如下:
我们应该注意以下几个方面:
- 现在有 22 位(而不是 32 位)用于标识对象类类型。这意味着我们可以加载到 JVM 进程中的不同类类型的数量约为 ~400 万个。
- 哈希代码的大小不会改变。
- 锁定操作不再覆盖标记字。这将保留压缩的类指针。
- GC 转发操作变得更加复杂,以便保留对压缩类指针的直接访问。
- 有四个未使用的位保留用于将来的增强(例如 Project Valhalla)。
如果争用 Java 锁,则新实现需要查找保存锁信息的辅助数据结构的地址。这种方法称为 “对象监视器表” ,在 JDK 22 中实现,由默认打开的新开关激活。Compact 对象标头依赖于此机制。UseObjectMonitorTable
如果未找到阻碍因素,此功能将作为 JDK 24 的一部分发布(最初作为实验性功能),预计将于 2025 年 3 月发布。长期目标是让此机制成为受支持平台上的唯一标头表示形式,但这可能需要更多版本。它还取决于对实际工作负载的广泛测试,以及缺乏性能和其他回归。甚至还有正在进行的探索工作,看看是否有可能将标头大小减少到 32 位。
在 JDK 24(测试版或最终版)中推出后,应用程序团队可以通过命令行开关激活此新功能来测试其工作负载,并查找与之相关的性能差异,从而提供帮助。-XX:UseCompactObjectHeaders
原文地址:https://blog.csdn.net/lilinhai548/article/details/144360498
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!