
Spring
Oracle官方给出的Oracle JDK支持时间线如上图所示。从中能够发现,JDK 17的支持最长可延续到2029年9月。按照技术更新换代的速度,此次长达8年的免费商用期可谓用心良苦,旨在让使用者能安心地将JDK升级到JDK 17(不过JDK 8的支持时间更长,可延长至2030年12月,JDK 8真的是永远的神!)自JDK诞生至今,处于长期支持状态的版本主要有JDK 7、JDK 8、JDK 11以及JDK 17。JDK 17会是继Java 8之后最为重要的长期支持(LTS)版本,它是Java社区8年努力的结晶。一直以来,Java 8都是Java社区的一个痛点。Java 8提供了诸多特性,像是Lambda表达式、Optional类,再加上其超长的支持时间,这些因素使得JDK 8至今仍在被使用。这体现了以稳定性为导向的企业管理层和追求变化的程序员之间的博弈。不升级成为各大企业心照不宣的决策。如今,这种平衡或许会被打破。因为在Java领域占据霸主地位的框架SpringBoot,其选择支持的最小Java长期支持版本是最新的Java 17。那么接下来,就让我们一同来看看,从JDK 8到JDK 17,Java社区这8年努力取得了哪些成果?重要特性:重点在于API的优化,像是支持HTTP2的客户端API,还有JVM将G1设为默认垃圾收集器。重要特性:借助var关键字达成局部变量类型推断,这让Java变成弱类型语言。JVM的G1垃圾回收从单线程变为多线程并行处理,从而减少G1的停顿时间。重要特性:完善JDK9与JDK10,重点是增强Stream、集合等API,并且新增ZGC垃圾收集器。重要特性包括:switch表达式语法得到扩展,G1收集器得以优化,还新增了Shenandoah GC垃圾回收算法。重要特性:ZGC优化,将内存释放回操作系统,socket底层实现采用NIO。JDK16相当于正式引入了JDK14、JDK15的部分特性,像instanceof模式匹配以及record的引入等,到了JDK16这些特性都成为了最终的版本。JDK17属于LTS版本,不过它不像JDK8与JDK11那样有很突出的特性,它主要是对之前版本的整合、完善。重要特性详细解读Java的模块化相关内容。Java 9发行版的核心亮点是JPMS(Java Platform Module System),它也被叫做Jigshaw项目。模块是一种新的结构,就如同我们已有的包一样。通过新的模块化编程开发出来的应用程序,可被视为交互模块的集合,这些模块之间有着明确界定的边界与依赖关系。JPMS包含对编写模块化应用程序的支持,还涉及将JDK源代码模块化。JDK 9包含了大概92个模块(在GA版本中可能会有变动)。Java 9模块系统中有一个名为Java.base的模块,它被视作基本模块,是一个独立的模块,不依赖其他任何模块,默认情况下,其他所有模块都依赖Java.base。在Java模块化编程里:典型的module - info.Java类如下:总结而言,模块化旨在使JDK的各个组件能够被拆分、复用以及替换重写。例如,若对Java的GUI不满,可自行实现一个;若对Java语法不满,能将Javac替换为其他语言及其编译器,像Kotlin和Kotlinc等。要是没有模块化,这几乎难以达成。每次修改某个模块时,总不能重新编译整个JDK再发布一个全新SDK吧。模块化有助于更高效地定制与部署。本地变量的类型推断。在Java 10之前,定义局部变量时,需在赋值左侧提供显式类型,在右侧提供实现类型。Java 10有本地变量类型推断功能,能用var声明变量。Java 10为开发者提供了本地变量类型推断这一语法糖,会引入var关键字,无需明确规范变量类型。尽管我们在代码里用var定义,但虚拟机并不认识它。在把Java文件编译成class文件时会进行解糖操作,以变量的真实类型取代var。HttpClient的HTTP客户端API通过响应式流实现。Java利用HttpURLConnection开展HTTP通信已有很长时间了。不过,随着时间不断推移,需求变得日益复杂,应用程序的要求也越来越高。在Java 11之前,开发人员只能借助功能多样的库,像Apache HttpComponents或者OkHttp之类的。我们发现Java 9发布时包含了一个HttpClient实现,当时它是作为实验性的功能。这个功能逐步发展,到Java 11时成为最终功能。如今,Java应用程序进行HTTP通信无需任何外部依赖了。作为JDK11正式推出的新Http连接器,它所支持的功能比较新颖,主要特性如下:HTTP2.0其他客户端也可支持,HttpClient以CompletableFuture作为异步返回数据的方式。HttpClient的一大优势在于支持WebSocket,并且它对响应式流的支持也是优势之一。HttpClient的NIO模型、函数式编程、CompletableFuture异步回调以及响应式流,这些使其具备很强的并发处理能力,进而性能非常高,而且内存占用量也更少。 语法糖Collectors::teeing已将teeing收集器公开为静态方法。这个收集器会把输入转发给另外两个收集器,再用函数合并它们的结果。 示例:箭头表达式获得支持(在jdk12为预览,jdk14成标准)。switch语句经过更改得以扩展,既能作语句也能作表达式。无需在每个case块定义break语句,简单使用箭头语法就行。jdk13中的yield关键字。通过yield,现在能有效地从switch表达式返回值了,也更易于实现策略模式。早前,我们为把JSON嵌入代码,将它声明为字符串文字。
之前:传统的Java应用程序会创建一个类,利用其构造方法实例化类,再用getter和setter方法访问或设置成员变量的值。而有了record关键字后,代码就会变得更为简洁。 JVMJDK9时将G1设置为JVM默认的垃圾收集器。到了JDK10,并行全垃圾回收器G1采用并行Full GC来改善其延迟,其full GC的实现从JDK10开始由单线程 - 清除 - 压缩算法转变为并行化 - 清除 - 压缩算法。JDK11推出了实验性的新一代垃圾回收器ZGC,它的目标是让GC暂停时间不超过10ms,可处理小到几百兆、大到几个T的堆。JDK14删除了CMS垃圾回收器,弃用ParallelScavenge + SerialOld GC的垃圾回收算法组合,还把zgc垃圾回收器移植到macOS和Windows平台。JDK15中ZGC(JEP 377)和Shenandoah(JEP 379)不再是实验性功能,但默认的GC依旧是G1。JDK16对ZGC进行增强,ZGC获得46个增强功能与25个错误修复,能控制stw时间不超过10毫秒。

Java
在GC延迟上,JDK 17的提升更为显著。能看出为减少GC暂停时长所付出的努力都有了回报,许多提升得益于GC的改进。在Parallel里,JDK 17相较于JDK 8和JDK 11提升了40%;在G1中,JDK 11比JDK 8提升26%,JDK 17较JDK 8提升近60%。在ZGC方面,JDK 17比JDK 11提升超40%。
在JDK 17里,ZGC远未达到亚毫秒级暂停时间这一目标。G1旨在平衡延迟与吞吐量,其暂停时间远低于默认的200毫秒目标。ZGC的设计确保暂停时间不受堆大小影响,当堆扩展到128GB时这一情况清晰可见。从暂停时间方面考量,G1在处理更大堆时比Parallel更具优势,因为G1能保证暂停时间达到特定目标。
上图对三个不同收集器原生内存的使用峰值进行了比较。鉴于从这个角度看,Parallel和ZGC都极为稳定,所以我们有必要查看一下原始数据。可以发现,G1在这方面确实有了改进,主要是因为各项功能及其增强功能提升了记忆集管理的效率。不管使用哪种收集器,与旧版本相比,JDK 17的整体性能都有大幅提升。在JDK 8里,Parallel为默认设置,到JDK 9时则改为G1。从那之后,G1的改进速度就超过了Parallel,不过在某些情况下,Parallel可能依旧是最佳选择。而JDK 15正式启用的ZGC的加入,使之成为了第三种高性能替代方案。 其他在Java15之前,只要被继承类不是final类型,所有类都能无限制地继承其他类,任何类也都可实现公共接口。而到了Java15,类或者接口能用修饰符sealed声明为密封类或接口,从而限制其继承类。Java 15通过JEP 339添加了另一种数字签名方案EdDSA(Edwards - Curve Digital Signature ALGorithm)。与其他已有的签名方案相比,EdDSA有着更好的性能,且能提供更安全的签名。总结:1. Spring一马当先,直奔JDK17。要是Spring6仍支持Java8,许多技术框架就得跟着兼容Java8。与其如此,不如Spring带个头,一起迈向Java17,只是部分框架还不支持JDK17。2.性能得到了升级,仅仅将Java8换成Java11,啥都没做性能就直接提升了10%(这是由于nio底层重写),更不用说从Java11到jdk17过程中JVM的相关优化了。但仅仅是性能优化还不能吸引企业去升级JDK,毕竟增加机器就能解决问题,没必要进行各种升级改造,而且还可能存在安全问题。JDK21有望成为真正的经典版本。当前它还不具备Project loom功能,这意味着没有协程,其性能与具备协程的JDK相比差很多。像阿里开源的JDK8、11就有非侵入式协程。从发展态势来看,Project loom功能在JDK19中已经可以预览了,能看到这个版本里许多Java工具都开始针对loom进行升级。Project loom大概会在JDK21正式推出,而JDK21是一个长期支持版本(LTS),值得期待。各类servlet容器,还有jetty、netty、vert.x等,在它们最新版本的发行说明里能找到相应的升级标注,内容为我们添加了某些支持,其中最重要的就是对loom(或者称为虚拟线程)的支持。可以预料,一旦JDK21发布,很多软件都会跟进并投入生产。JDK升级是必然的发展趋势。那些不打算升级的人认为,在国内,很多程序员可能觉得升级会带来额外工作,要是出了问题就会费力不讨好,要是出现安全问题就更麻烦了。还有人觉得升级没有实质好处,反而存在风险。从企业角度来看,由于要去Oracle化,所以未来也不打算升级。然而,考虑到Oracle将来不再维护JDK8,Spring也不再维护旧版本,为了跟上时代步伐,使用最新技术,这必然会推动JDK升级。随着越来越多的公司开始使用JDK17及以上版本,未来更多框架的新版本将最低支持JDK17,因为兼容旧版本的JDK实在不划算。当大部分框架、社区和论坛都在讨论JDK17的技术以及解决问题的方法时,必然会促使企业进行升级。
Copyright © 2025 IZhiDa.com All Rights Reserved.
知答 版权所有 粤ICP备2023042255号