Java 平台演进

Java 自 1995 年问世以来,已被全球近乎所有国家/地区的超过 1000 万名开发者使用。它确实是历史上最成功的技术之一。但这并不意味着该平台停滞不前。实际上恰恰相反。

Java 8 于 2014 年发布,为 Java 平台带来了 Lambda 表达式 以及 Stream API、Optional 类以及许多其他出色功能。这是 Java 8 成为 Java 历史上最受欢迎版本的原因之一。即使在今天,它仍然是 Java 最广泛使用的版本之一。

但是,如今选择 Java 8 会阻止开发者获得语言、JVM、工具等方面巨大进步的访问权限。本文将尝试总结这些进步中的大部分。但不要只听我们说,今天就试试 最新版本的 Java

 

深思熟虑的演进

在我们深入探讨之前,让我们花点时间了解一下 Java 管理者如何看待 Java 平台的演进。Java 语言架构师 Brian Goetz 对此主题谈论了很多。特别是他的一个演讲,Stewardship: The Sobering Parts,是一个很好的起点。Brian 谈论了多年来担任语言管理者的挑战和乐趣,以及如何谨慎地平衡保守主义力量(行动缓慢,保持兼容性)和创新力量(行动迅速,适应变化),最终发现自己总是会惹恼两边的人。


在我们的 管理 页面上了解更多信息,其中包含来自 Mark ReinholdJohn Rose 的演讲。

 

加速创新

现在,考虑到这种深思熟虑的演进以及对保守主义和创新的谨慎平衡,Java 团队着手提高创新速度。这项努力的基础是改变 Java 长期以来的发布节奏,该节奏以多年周期为单位,以功能为驱动。Java 在 Mark Reinhold 在他的 Moving Java Forward Faster 文章中首次提出的建议下,于 2017 年转向了 6 个月的基于时间的发布节奏,每 3 月和 9 月都会发布一个新的 Java 功能版本。这种转变对生态系统产生了巨大的影响,原因很多,有些显而易见,有些则不那么明显。

Release Cadence

对社区来说,显而易见的好处是开发者能够每 6 个月而不是每 2-3 年就能接触到新的 Java 功能。多年等待时间太长了,这给了开发者很多机会去寻找其他工具来解决他们的问题。这种周期导致了 Java 停滞不前的看法,即使它并没有停滞不前。请考虑以下情况:在 2017 年发布 Java 9 之后,根据旧的节奏,下一个版本可能会在 2020 年发布。三年时间可以发生很多事情——在 Java 中,确实发生了很多事情!例如,在新的节奏下,我们在 2018 年的 Java 10 中发布了 var,并在 2019 年的 Java 12 中对 G1 垃圾回收器进行了重大改进。由于每六个月的版本中都包含各种新功能,因此没有理由只每三年查看一次 Java 而错过这些功能。

此外,通过 6 个月的周期,该团队能够有效地引入(或改进)模型来引入功能,例如 预览系统 和基于时间的 早期访问构建,在功能成为标准之前从社区收集反馈,届时这些功能将存在很长时间。

更重要的是,发布节奏使团队能够将大型功能(Project Loom、Panama 等)分解,并随着时间的推移以增量更改的形式引入它们,从而实现更好的项目规划和更好的最终用户体验。可以使用 CI/CD 管道自动测试和引入新版本的 Java,而不是进行大型的、令人恐惧的停止世界事件,用户将有充足的准备时间来适应新功能。有关此方面的示例,请参阅下面有关 Project Amber 的部分。

最后,一个不那么明显的好处是,为 Java 平台本身工作的团队的生产力和幸福感得到了提升。发布现在大多是“非事件”,因为它们已经稳定下来,准备就绪,并且在许多情况下,已经通过我们的预览和早期访问模型在野外进行了数周甚至数月的测试。

 

自 8 以来快照

为了获得更易于维护的程序,请查看 记录密封类模式匹配

为了获得更简洁的程序,请查看 局部接口隐式声明的类和实例主方法(预览)。

为了获得无痛的多行字符串,请查看 文本块字符串模板(预览)。

为了减少编写、维护和观察高吞吐量并发应用程序的工作量,请查看 虚拟线程

为了获得更好的文档,请查看 javadoc 搜索代码片段

为了进行实验和学习,请查看 jshell简单 Web 服务器Java 游乐场

为了更轻松地进行调试,请查看 有用的 NullPointerExceptionsJFR 事件流

对于自 8 以来所有新内容的完整清单,请继续滚动到 清单 部分。

 

Project Amber 实践

一张图片胜过千言万语。以下图片代表了 Project Amber、发布节奏和预览系统在过去几年的实践。如您所见,Amber 的许多语言功能最初都是预览功能,目的是收集更广泛的反馈,有时在成为标准之前还会进行一些细微的调整。

Amber in Action

wikiInside.java 上了解有关 Project Amber 的更多信息。

在此处了解有关预览系统的更多信息 此处

 

性能

多年来,Java 平台最重要的演进之一是性能。从仅仅升级就能获得“开箱即用”的性能,到利用现代硬件,再到使用非常大的堆获得一致的暂停时间,Java 平台在每个版本中都变得越来越好。

在 Java GC 团队的帮助下,以下是随着时间的推移性能演进的一些快照,摘自 Stefan Johansson 的 博客文章。要从 Java 团队直接获取更多有关性能的精彩信息,请查看 Inside.java

所有结果均来自运行 SPECjbb 2015 基准测试,固定堆大小为 16GB,并且没有调整 GC 参数。首先,您可以看到每个收集器在 Java 17 中实现的吞吐量高于以前版本。ZGC 在 Java 15 中达到生产状态。

Throughput

这些是平均暂停时间,针对每个收集器依次进行了归一化。17 中的 Parallel 的平均暂停时间大约是 8 中的平均暂停时间的 60%。G1 也是如此。

这是一个尝试在 17 上运行应用程序的充分理由。当然,您的目光会被吸引到 ZGC 区域。17 中的 ZGC 的暂停时间远低于 15 中的暂停时间。

Pause Times

这是一个 ACTUAL 平均暂停时间的 LOG 图,但添加了一列用于 128GB 堆。由于 ZGC 是完全并发的,因此它在与其他收集器相同的负载下实现了亚毫秒的暂停时间。

请注意,Parallel 和 G1 在 8 和 17 之间已经有了很大的改进,因此您可能能够将数据大小增加八倍,并且在 17 中仍然可以比在 8 中获得更短的暂停时间。请仔细思考一下。您可能能够将数据大小 **增加八倍**,并且在 17 中仍然可以获得 **更短** 的暂停时间,而无需更改代码、进行特殊调整或使用第三方工具。只需使用您熟悉和喜爱的 Java 即可。

您还会注意到 ZGC 的暂停时间是恒定的。您可以调整 G1 和 Parallel 以获得更短的暂停时间,但很难达到 ZGC 的水平。当您的产品面临数据处理量增加 10 倍的情况时,最好的应对措施是迁移到 Java 17 并利用 G1 和 ZGC。

Actual Pause Times

最后,让我们考虑一下占用空间。占用空间是指 GC 数据结构在本地内存中的开销,因此 Java 堆无法使用该内存。使用较少本地内存的 GC 使您能够在同一台机器上并置更多 JVM。

回到 Java 8,在 G1 成为默认值之前,它的开销通常约为 20%,而在 Java 17 中,该开销已降至约 10%。此基准测试相对友好:它显示了 Java 8 中 G1 的开销约为 10%,而在 Java 17 中降至约 5%。

这与 Parallel 收集器的开销大致相同,因此从 8 迁移到 17 并获得默认的 G1 应该不会对内存造成重大影响。

我们看到,ZGC 的低延迟确实会带来更高的占用空间成本,但这将在后续版本中得到改进。

Footprint

 

自 8 以来清单

对于那些想要查看自 Java 8 以来 Java 平台改进的更详细清单的人,以下按类别进行分类,以便于浏览。

语言功能

库和工具

安全

可观察性和调试

垃圾回收

现代化基础设施

移除和弃用

其他

附加部分:预览/孵化器功能

更多学习

最后更新: 2023 年 11 月 14 日


返回教程列表