IT博文
MySQL 事务隔离级别详解
使用 docker compose 安装 tidb
架构师日记-如何写的一手好代码
生产事故-记一次特殊的OOM排查
Docker安装RabbitMQ——基于docker-compose工具
使用 docker-compose 部署单机 RabbitMQ
只需3步,即刻体验Oracle Database 23c
长达 1.7 万字的 explain 关键字指南!
Redis为什么能抗住10万并发?揭秘性能优越的背后原因
深度剖析Redis九种数据结构实现原理
【绩效季】遇到一个好领导有多重要,从被打差绩效到收获成长
为什么Redis不直接使用C语言的字符串?
Java阻塞队列中的异类,SynchronousQueue底层实现原理剖析
如何调整和优化 Go 程序的内存管理方式?
应用部署引起上游服务抖动问题分析及优化实践方案
Java 并发工具合集 JUC 大爆发!!!
卷起来!!这才是 MySQL 事务 & MVCC 的真相。
JDK8 到 JDK17 有哪些吸引人的新特性?
告别StringUtil:使用Java 11的全新String API优化你的代码
从JDK8飞升到JDK17,再到未来的JDK21
Java JMH Benchmark Tutorial
linux和macOS下top命令区别
Windows10关闭Hyper-V的三种方法
为什么应该选择 POSTGRES?
阿里云对象存储 OSS 限流超过阈值自动关闭【防破产,保平安】
Java高并发革命!JDK19新特性——虚拟线程(Virtual Threads)
“请不要在虚拟机中运行此程序”的解决方案
Spring中的循环依赖及解决
浅谈复杂业务系统的架构设计 | 京东云技术团队
面试题:聊聊TCP的粘包、拆包以及解决方案
操作日志记录实现方式
字节跳动技术团队-慢 SQL 分析与优化
Spring Boot 使用 AOP 防止重复提交
Controller层代码就该这么写,简洁又优雅!
SpringBoot 项目 + JWT 完成用户登录、注册、鉴权
重复提交不再是问题!SpringBoot自定义注解+AOP巧妙解决
SpringBoot 整合 ES 实现 CRUD 操作
SpringBoot 整合 ES 进行各种高级查询搜索
SpringBoot操作ES进行各种高级查询
SpringBoot整合ES查询
如何做架构设计? | 京东云技术团队
最值得推荐的五个VPN软件(便宜+好用+稳定),靠谱的V2ray梯子工具
我说MySQL每张表最好不超过2000万数据,面试官让我回去等通知?
vivo 自研鲁班分布式 ID 服务实践
使用自带zookeeper超简单安装kafka
推荐 6 个很牛的 IDEA 插件
喜马拉雅 Redis 与 Pika 缓存使用军规
「程序员转型技术管理」必修的 10 个能力提升方向
jdk17 下 netty 导致堆内存疯涨原因排查 | 京东云技术团队
如何优雅做好项目管理?
MySQL 到 TiDB:Hive Metastore 横向扩展之路
聊聊即将到来的 MySQL5.7 停服事件
Linux终端环境配置
微软 Edge 浏览器隐藏功能一览:多线程下载、IE 模式、阻止视频自动播放等
Hutool 中那些常用的工具类和实用方法
clash 内核删库?汇总目前常用的内核仓库和客户端
JDK11 升级 JDK17 最全实践干货来了 | 京东云技术团队
我是如何写一篇技术文的?
虚拟线程原理及性能分析
Java线程池实现原理及其在美团业务中的实践
Editplus和EmEditor配置一键编译java运行环境
用Spring Boot 3.2虚拟线程搭建静态文件服务器有多快?
SpringBoot中使用LocalDateTime踩坑记录 - 程序员偏安 - 博客园
程序员必备!10款实用便捷的Git可视化管理工具 - 追逐时光者 - 博客园
基于Netty开发轻量级RPC框架
开发Java应用时如何用好Log
复杂SQL治理实践 | 京东物流技术团队
火山引擎ByteHouse:分析型数据库如何设计并发控制?
多次崩了之后,阿里云终于改了
推荐程序员必知的四大神级学习网站
初探分布式链路追踪
新项目为什么决定用 JDK 17了
Java上进了,JDK21 要来了,并发编程再也不是噩梦了
mapstruct这么用,同事也开始模仿
再见RestTemplate,Spring 6.1新特性:RestClient 了解一下!
【MySQL】MySQL表设计的经验(建议收藏)
如何正确地理解应用架构并开发
解读工行专利CN112905176B
工商银行取得「基于 Spring Boot 的 web 系统后端实现方法及装置」专利
IDEA 2024.1:Spring支持增强、GitHub Action支持增强、更新HTTP Client等
TIOBE 2 月:Go 首次进入前十、“上古语言” COBOL 和 Fortran 排名飙升
Java 21 虚拟线程如何限流控制吞吐量
🎉 通用、灵活、高性能分布式 ID 生成器 | CosId 2.6.6 发布
20年编程,AI编程6个月,关于Copliot辅助编码工具,你想知道的都在这里
Java 8 内存管理原理解析及内存故障排查实践
消息队列选型之 Kafka vs RabbitMQ
从 MongoDB 到 PostgreSQL 的大迁移
腾讯云4月8日故障复盘及情况说明
PHP 在 2024 年还值得学习吗?
AMD集显安装显卡驱动之后出现黑屏,建议这样解决
使用 Docker 部署 moments 微信朋友圈 - 谱次· - 博客园
Java 17 是最常用的 Java LTS 版本
盘点Lombok的几个骚操作
Llama 3 + Ollama + Open WebUI打造本机强大GPT
如何优雅地编写缓存代码
Gmeek快速上手
笔记软件思源远程和本地接入大语言模型服务Ollama实现AI辅助写作(Windows篇)
Git Subtree:简单粗暴的多项目管理神器
这款轻量级规则引擎,真香!!
Ollama教程:本地LLM管理、WebUI对话、Python/Java客户端API应用
GLM-4-9B支持 Ollama 部署
智谱AI开源代码生成大模型第四代版本:CodeGeeX4-ALL-9B
美团二面:如何保证Redis与Mysql双写一致性?连续两个面试问到了!
免费开源好用,Obsidian和Omnivore真正实现一键联动剪藏文章,手把手教程!
得物 Redis 设计与实践
架构图怎么画?手把手教您,以生鲜电商为例剖析业务/应用/数据/技术架构图
使用Hutool要注意了!升级到6.0后你调用的所有方法都将报错 - 掘金
别再用雪花算法生成ID了!试试这个吧
无敌的Arthas!
Navicat Premium v16、v17 破解激活
🎉 分布式接口文档聚合,Solon 是怎么做的?
深入体验全新 Cursor AI IDE 后,说杀疯了真不为过!
Nacos 3.0 架构全景解读,AI 时代服务注册中心的演进
本文档使用 MrDoc 发布
-
+
从JDK8飞升到JDK17,再到未来的JDK21
> 2022年,Spring6和 SpringBoot3都推出了,在此之前,Java社区很坚挺,一直是"新版任你发,我用Java 8",不管新版本怎么出,很少有人愿意升级。 这一次,Spring 直接来了个大招,SpringBoot3和Spring6的最低依赖就是JDK17!跨过 JDK 8-16,直接升级到 JDK 17。那么为什么是 JDK 17呢? 作者 | 唐岳平(凌力) 来源 | 阿里开发者公众号 ### 背景 2022年,Spring6和 SpringBoot3都推出了,在此之前,Java社区很坚挺,一直是"新版任你发,我用Java 8",不管新版本怎么出,很少有人愿意升级。 这一次,Spring 直接来了个大招,SpringBoot3和Spring6的最低依赖就是JDK17!跨过 JDK 8-16,直接升级到 JDK 17。那么为什么是 JDK 17呢? ### 为什么是JDK17 这么多新版本的 JDK,而且2022年还会推出 JDK 18 和 JDK 19,为什么 Spring 选择了 JDK 17呢。 主要是因为他是一个 Oracle官宣可以免费商用的LTS版本,所谓 LTS,是 Long Term Support,也就是官方保证会长期支持的版本。  上面这张图是 Oracle 官方给出的 Oracle JDK 支持的时间线。可以看得到,JDK 17 最多可以支持到 2029 年 9 月份。按照技术更新迭代的速度,这次免费商用 8 年可谓是良苦用心,为的就是让使用者放心大胆地将 JDK 升级到 JDK 17(不过JDK 8 支持的时间更长,可以延长到 2030 年 12 月,JDK8可谓是YYDS!) 从 JDK 诞生到现在,还在长期支持的版本主要有 JDK 7、JDK 8 、JDK 11以及 JDK 1,JDK 17 将是继 Java 8 以来最重要的LTS版本,是 Java 社区八年努力的成果。 一直以来,Java8 都是 Java 社区心头的痛,Java8提供了很多特性,比如Lambda 表达式、Optional 类,加上Java8超长的支持时间,都导致了JDK8的使用至今。它代表着以稳定性为主的企业管理层与拥抱变化为主的程序猿之间的拉锯战。不升!成为各大厂心照不宣的选择。现在,这种平衡或将打破。因为 Java 届的霸主框架 SpringBoot,选择了最小支持的 Java lts 版本,就是最新的 Java17。 那么接下来,让我们看看,从JDK8到JDK17,Java 社区八年努力的成果有哪些? ## 从JDK8到JDK17的新特性 ### JDK9新特性(2017年9月) - 模块化 - 提供了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法 - 接口支持私有方法 - Optional 类改进 - 多版本兼容Jar包 - JShell工具 - try-with-resources的改进 - Stream API的改进 - 设置G1为JVM默认垃圾收集器 - 支持http2.0和websocket的API **重要特性:主要是API的优化,如支持HTTP2的Client API、JVM采用G1为默认垃圾收集器** ### JDK10新特性(2018年3月) - 局部变量类型推断,类似JS可以通过var来修饰局部变量,编译之后会推断出值的真实类型 - 不可变集合的改进 - 并行全垃圾回收器 G1,来优化G1的延迟 - 线程本地握手,允许在不执行全局VM安全点的情况下执行线程回调,可以停止单个线程,而不需要停止所有线程或不停止线程 - Optional新增orElseThrow()方法 - 类数据共享 - Unicode 语言标签扩展 - 根证书 **重要特性:通过var关键字实现局部变量类型推断,使Java语言变成弱类型语言、JVM的G1垃圾回收由单线程改成多线程并行处理,降低G1的停顿时间** ### JDK11新特性(2018年9月)(LTS版本) - 增加一些字符串处理方法 - 用于 Lambda 参数的局部变量语法 - Http Client重写,支持HTTP/1.1和HTTP/2 ,也支持 websockets - 可运行单一Java源码文件,如:java Test.java - ZGC:可伸缩低延迟垃圾收集器,ZGC可以看做是G1之上更细粒度的内存管理策略。由于内存的不断分配回收会产生大量的内存碎片空间,因此需要整理策略防止内存空间碎片化,在整理期间需要将对于内存引用的线程逻辑暂停,这个过程被称为"Stop the world"。只有当整理完成后,线程逻辑才可以继续运行。(并行回收) - 支持 TLS 1.3 协议 - Flight Recorder(飞行记录器),基于OS、JVM和JDK的事件产生的数据收集框架 - 对Stream、Optional、集合API进行增强 重要特性:对于JDK9和JDK10的完善,主要是对于Stream、集合等API的增强、新增ZGC垃圾收集器 ### JDK12新特性(2019年3月) - Switch 表达式扩展,可以有返回值 - 新增NumberFormat对复杂数字的格式化 - 字符串支持transform、indent操作 - 新增方法Files.mismatch(Path, Path) - Teeing Collector - 支持unicode 11 - Shenandoah GC,新增的GC算法 - G1收集器的优化,将GC的垃圾分为强制部分和可选部分,强制部分会被回收,可选部分可能不会被回收,提高GC的效率 **重要特性:switch表达式语法扩展、G1收集器优化、新增Shenandoah GC垃圾回收算法** ### JDK13新特性(2019年9月) - Switch 表达式扩展,switch表达式增加yield关键字用于返回结果,作用类似于return,如果没有返回结果则使用break - 文本块升级 """ ,引入了文本块,可以使用"""三个双引号表示文本块,文本块内部就不需要使用换行的转义字符 - SocketAPI 重构,Socket的底层实现优化,引入了NIO - FileSystems.newFileSystem新方法 - ZGC优化,增强 ZGC 释放未使用内存,将标记长时间空闲的堆内存空间返还给操作系统,保证堆大小不会小于配置的最小堆内存大小,如果堆最大和最小内存大小设置一样,则不会释放内存还给操作系统 **重要特性:ZGC优化,释放内存还给操作系统、socket底层实现引入NIO** ### JDK14新特性(2020年3月) - instanceof模式匹配,instanceof类型匹配语法简化,可以直接给对象赋值,如if(obj instanceof String str),如果obj是字符串类型则直接赋值给了str变量 - 引入Record类型,类似于Lombok 的@Data注解,可以向Lombok一样自动生成构造器、equals、getter等方法; - Switch 表达式-标准化 - 改进 NullPointerExceptions提示信息,打印具体哪个方法抛的空指针异常,避免同一行代码多个函数调用时无法判断具体是哪个函数抛异常的困扰,方便异常排查; - 删除 CMS 垃圾回收器 ### JDK15新特性(2020年9月) - EdDSA 数字签名算法 - Sealed Classes(封闭类,预览),通过sealed关键字修饰抽象类限定只允许指定的子类才可以实现或继承抽象类,避免抽象类被滥用 - Hidden Classes(隐藏类) - 移除 Nashorn JavaScript引擎 - 改进java.net.DatagramSocket 和 java.net.MulticastSocket底层实现 ### JDK16新特性(2021年3月) - 允许在 JDK C ++源代码中使用 C ++ 14功能 - ZGC性能优化,去掉ZGC线程堆栈处理从安全点到并发阶段 - 增加 Unix 域套接字通道 - 弹性元空间能力 - 提供用于打包独立 Java 应用程序的 jpackage 工具 **JDK16相当于是将JDK14、JDK15的一些特性进行了正式引入,如instanceof模式匹配(Pattern matching)、record的引入等**最终到JDK16变成了final版本 ### JDK17新特性(2021年9月)(LTS版本) - Free Java License - JDK 17 将取代 JDK 11 成为下一个长期支持版本 - Spring 6 和 Spring Boot 3需要JDK17 - 移除实验性的 AOT 和 JIT 编译器 - 恢复始终执行严格模式 (Always-Strict) 的浮点定义 - 正式引入密封类sealed class,限制抽象类的实现 - 统一日志异步刷新,先将日志写入缓存,然后再异步刷新 **虽然JDK17也是一个LTS版本,但是并没有像JDK8和JDK11一样引入比较突出的特性,主要是对前几个版本的整合和完善。** ## 重要特性详解 ### Java 模块化 JPMS(Java Platform Module System)是Java 9发行版的核心亮点。它也被称为[Jigshaw项目](https://link.zhihu.com/?target=https%3A//openjdk.java.net/projects/jigsaw/)。模块是新的结构,就像我们已经有包一样。使用新的模块化编程开发的应用程序可以看作是交互模块的集合,这些模块之间具有明确定义的边界和依赖关系。 JPMS包括为编写模块化应用程序提供支持,以及将JDK源代码模块化。JDK 9 附带了大约 92 个模块(在 GA 版本中可以进行更改)。Java 9 Module System有一个**"java.base"**模块。它被称为基本模块。它是一个独立的模块,不依赖于任何其他模块。默认情况下,所有其他模块都依赖于"java.base"。 在java模块化编程中: - 一个模块通常只是一个 jar 文件,在根目录下有一个文件module-info.class。 - 要使用模块,请将 jar 文件包含到modulepath而不是classpath. 添加到类路径的模块化 jar 文件是普通的 jar 文件,module-info.class文件将被忽略。 典型的module-info.java类如下所示: ```text module helloworld { exports com.alibaba.eight; } module test { requires helloworld; } ``` **总结:模块化的目的,是让jdk的各个组件可以被分拆,复用和替换重写,**比如对java的gui不满意,可以自己实现一个gui,对java的语法不满意,可以把javac替换成其他语言和其他语言的编译器,比如kotlin和kotlinc等,没有模块化,几乎很难实现,每次修改某个模块,总不能把整个jdk给重新编译一遍,再发布一个整个sdk吧,模块化可以帮助更有效的定制化和部署 ### **本地变量类型推断** 在Java 10之前版本中,我们想定义定义局部变量时。我们需要在赋值的左侧提供显式类型,并在赋值的右边提供实现类型: MyObject value = new MyObject(); 在Java 10中,提供了本地变量类型推断的功能,可以通过var声明变量: var value = new MyObject(); 本地变量类型推断将引入“var”关键字,而不需要显式的规范变量的类型。 其实,所谓的本地变量类型推断,也是Java 10提供给开发者的语法糖。 虽然我们在代码中使用var进行了定义,但是对于虚拟机来说他是不认识这个var的,在java文件编译成class文件的过程中,会进行解糖,使用变量真正的类型来替代var ### HTTP客户端API-响应式流实现的HttpClient Java 使用HttpURLConnection进行HTTP通信已经很长一段时间了。但随着时间的推移,要求变得越来越复杂,应用程序的要求也越来越高。在 Java 11 之前,开发人员不得不求助于功能丰富的库,如_Apache HttpComponents_或_OkHttp_等。 我们看到Java 9发布包含一个HttpClient实现作为实验性功能。它随着时间的推移而发展,现在是 Java 11 的最终功能。现在 Java 应用程序可以进行 HTTP 通信,而无需任何外部依赖。 作为JDK11中正式推出的新Http连接器,支持的功能还是比较新的,主要的特性有: - 完整支持HTTP 2.0 或者HTTP 1.1 - 支持 HTTPS/TLS - 有简单的阻塞使用方法 - 支持异步发送,异步时间通知 - 支持WebSocket - 支持响应式流 HTTP2.0其他的客户端也能支持,而HttpClient使用CompletableFuture作为异步的返回数据。WebSocket的支持则是HttpClient的优势。响应式流的支持是HttpClient的一大优势。 HttpClient中的NIO模型、函数式编程、CompletableFuture异步回调、响应式流让HttpClient拥有极强的并发处理能力,所以其性能极高,而内存占用则更少。 ### 语法糖 ### Stream API 改进 ### Collectors.teeing() teeing 收集器已公开为静态方法**Collectors::teeing**。该收集器将其输入转发给其他两个收集器,然后将它们的结果使用函数合并。 **示例:** ```text List<Student> list = Arrays.asList( new Student("唐一", 55), new Student("唐二", 60), new Student("唐三", 90)); //平均分 总分 String result = list.stream().collect(Collectors.teeing( Collectors.averagingInt(Student::getScore), Collectors.summingInt(Student::getScore), (s1, s2) -> s1 + ":" + s2)); //最低分 最高分 String result2 = list.stream().collect(Collectors.teeing( Collectors.minBy(Comparator.comparing(Student::getScore)), Collectors.maxBy(Comparator.comparing(Student::getScore)), (s1, s2) -> s1.orElseThrow() + ":" + s2.orElseThrow() )); System.out.println(result); System.out.println(result2); ``` 添加Stream.toList方法(jdk16) ```text List<String> list = Arrays.asList("1", "2", "3"); //之前这样写 List<Integer> oneList = list.stream() .map(Integer::parseInt) .collect(Collectors.toList()); //现在可以这样写 List<Integer> twoList = list.stream() .map(Integer::parseInt) .toList(); ``` ### Switch表达式改进 支持箭头表达式(jdk12预览 jdk14标准) 此更改扩展了switch 语句以便它可以用作语句或表达式。不必为break每个 case 块定义一个语句,我们可以简单地使用**箭头语法** ```text boolean isWeekend = switch (day) { case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> false; case SATURDAY, SUNDAY -> true; default -> throw new IllegalStateException("Illegal day entry :: " + day); }; int size = 3; String cn = switch (size) { case 1 -> "壹"; case 2 -> "贰"; case 3, 4 -> "叁"; default -> "未知"; }; System.out.println(cn); ``` //要使用此预览功能,我们必须在应用程序启动期间使用–enable-preview标志明确指示 JVM。 yield关键字(jdk13) 使用yield,我们现在可以有效地从 switch 表达式返回值,并能够更容易实现策略模式。 ```text public class SwitchTest { public static void main(String[] args) { var me = 4; var operation = "平方"; var result = switch (operation) { case "加倍" -> { yield me * 2; } case "平方" -> { yield me * me; } default -> me; }; System.out.println(result); } } ``` ### 字符串 ### 文本块改进(jdk13) 早些时候,为了在我们的代码中嵌入 JSON,我们将其声明为_字符串_文字: String json = "{\\r\\n" + "\\"name\\" : \\"lingli\\",\\r\\n" + "\\"website\\" : \\"[https://www.alibaba.com/](https://link.zhihu.com/?target=https%3A//www.alibaba.com/)\\"\\r\\n" + "}"; _现在让我们使用字符串_文本块编写相同的 JSON : ```text String json = """ { "name" : "Baeldung", "website" : "https://www.alibaba.com/" } """; ``` 很明显,不需要转义双引号或添加回车。通过使用文本块,嵌入的 JSON 更易于编写,更易于阅读和维护。 ### 更多的API - isBlank():如果字符串为空或字符串仅包含空格(包括制表符),则返回 true。注意与isEmpty() 不同,isEmpty()仅在长度为 0 时返回 true。 - lines():将字符串拆分为字符串流,每个字符串包含一行。 - strip() : 分别从开头和结尾; - stripLeading()/stripTrailing()仅开始和仅结束删除空格。 - repeat(int times):返回一个字符串,该字符串采用原始字符串并按指定的次数重复该字符串。 - readString():允许从文件路径直接读取到字符串。 - writeString(Path path):将字符串直接写入指定路径处的文件。 - indent(int level):缩进字符串的指定量。负值只会影响前导空格。 - transform(Function f):将给定的 lambda 应用于字符串。 ### instanceof 的模式匹配(jdk14出预览,jdk16最终确认) ```text 之前: Object obj = "大阳"; if (obj instanceof String) { String t = (String) obj; // TODO } 现在: Object obj = "大阳"; if (obj instanceof String t) { // TODO 此时t已经是String类型了 } ``` ### record记录类(jdk16正式) 传统的Java应用程序通过创建一个类,通过该类的构造方法实例化类,并通过getter和setter方法访问成员变量或者设置成员变量的值。有了record关键字,你的代码会变得更加简洁。 ```text /** * record 记录类 * 你也可以覆写equals() hashCode() toString()方法,不用写get、set了 * @author DAYANG */ record User(String name, Integer age) { @Override public String toString() { return "User[" + "name='" + name + '\'' + ", age=" + age + ']'; } @Override public boolean equals(Object obj) { return false; } @Override public int hashCode() { return 0; } } ``` ### JVM ### GC变化 JDK9: 设置G1为JVM默认垃圾收集器 JDK10:并行全垃圾回收器 G1,通过并行Full GC, 改善G1的延迟。目前对G1的full GC的实现采用了单线程-清除-压缩算法。JDK10开始使用并行化-清除-压缩算法。 JDK11:推出ZGC新一代垃圾回收器(实验性),目标是GC暂停时间不会超过10ms,既能处理几百兆的小堆,也能处理几个T的大堆。 JDK14 :删除CMS垃圾回收器;弃用 ParallelScavenge + SerialOld GC 的垃圾回收算法组合;将 zgc 垃圾回收器移植到 macOS 和 windows 平台 JDk 15 : **ZGC** (JEP 377) 和**Shenandoah** (JEP 379) 不再是实验性功能。默认的 GC 仍然是**G1**。 JDK16:增强ZGC,ZGC获得了 46个增强功能 和25个错误修复,控制stw时间不超过10毫秒 ### 指标测试 ### 吞吐量比较  在吞吐量方面,Parallel 中 JDK 8 和 JDK 11 差距不大,JDK 17 相较 JDK 8 提升 15% 左右;G1 中 JDK 17 比 JDK 8 提升 18%;ZGC 在 [JDK 11](https://www.zhihu.com/search?q=JDK+11&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22article%22%2C%22sourceId%22%3A%22540350596%22%7D)引入,JDK 17 对比JDK 11 提升超过 20%。 ### 延迟比较  在 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 更善于处理更大的堆,因为它能够保证暂停时间满足特定目标。** ### 资源占用  上图比较了三个不同收集器原生内存的使用峰值。由于从这个角度来看 Parallel 和 ZGC 都非常稳定,因此我们应该看一看原始数字。我们可以看到 G1 在这方面确实有所改进,主要原因是所有功能和增强功能都提高了记忆集管理的效率 。 **总结:**无论使用哪种收集器,与旧版本相比,[JDK 17](https://www.zhihu.com/search?q=JDK+17&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22article%22%2C%22sourceId%22%3A%22441411555%22%7D) 的整体性能都有很大的提升。在 JDK 8 中,Parallel是默认设置,但在 JDK 9 中改为了 G1。从那以后,G1 的改进速度就超过了 Parallel,但在有些情况下可能 Parallel 仍然是最佳选择。而 ZGC(JDK 15 正式使用)的加入,成为了第三种高性能替代方案。 ### 其他 ### 密封类和接口(15预览 17正式) 在Java15之前,所有的类都可以没有限制地继承其他类--除非被继承类被声明为final类型,任何类都可以实现公共接口。 现在在Java15中,一个类或者接口可以使用修饰符sealed声明为密封类或者接口,来限制其继承类。 ```text /** * 定义一个抽象密封类Pet,它的实现类只能是Dog, Cat这两个,其他的实现类均不允许 */ public abstract sealed class Pet permits Dog, Cat {} final class Dog extends Pet { } final class Cat extends Pet { } //密封的类和接口限制了其他类或接口可以扩展或实现它们 public sealed interface Shape{ final class Planet implements Shape {} final class Star implements Shape {} final class Comet implements Shape {} } public abstract sealed class Test{ final class A extends Test {} final class B extends Test {} final class C extends Test {} } ``` ### EdDSA 算法 EdDSA (Edwards-Curve Digital Signature Algorithm) 是在 Java 15 中通过JEP 339添加的另一种附加数字签名方案。与其他可用的签名方案相比,它提供了更好的性能和安全的签名。 ## 总结和展望 ### 总结 **1.Spring带头猛冲,直接上JDK17。**如果Spring6还支持Java8的话,那很多技术框架都要跟着Java8的兼容,与其这样不如由Spring带头,一起飞升Java17,不过有些框架还不支持JDK17 **2.性能升级,**光从java8换到java11,啥也没干性能直接就提升了10%(nio底层的重写),更何况一路到jdk17过程中的JVM相关优化。 不过光是性能的优化还不足以吸引企业进行JDK升级,毕竟加机器就能解决,费不着各种升级改造,**还可能有安全问题** **3.JDK21可能成为真正的经典版本。**目前还没有Project loom功能,代表着没有协程,性能方面比有协程jdk差远了。比如阿里开源的jdk8,11,就有非侵入式协程,这方面比JDK17强。 从发展趋势看,Project loom功能在JDK19已经可预览了,可以发现该版本许多的java工具都开始针对loom进行升级,Project loom大概在JDK21进行正式推出,而JDK21又是一个长期支持版本 (LTS) ,值得期待。 各种servlet容器,还有jetty,netty,vert.x等,在它们最新版本的release note找到对应的升级标注,说,我们添加了某某支持,其中最重要的就是loom,或者叫做虚拟线程的支持, 可以预见一旦JDK21发行,很多软件都会跟上投入生产! ### 展望 **JDK的升级是必然趋势。** 不升级的人说,目前来说国内很多程序猿可能觉得升级会造成额外工作,出了问题费力不讨好,要是出了安全问题,更要提桶跑路。也有说没有实质性的好处,而且还有风险,还有从企业角度说,未来也不升级,因为去Oracle化。但考虑到未来oracle不再维护JDK8,Spring也不再维护过去版本的时候,为了跟上时代,使用最新技术,必然会助推JDK的升级。 当越来越多的公司加入到JDK17以上的大军中,未来更多的框架新版本都会最低支持JDK17,因为兼容旧JDK实在不值得,当大部分框架和社区、论坛都是讨论JDK17的技术和各种解决问题的方法时,必然会反推企业进行升级。 参考链接: > [https://zhuanlan.zhihu.com/p/480293185](https://zhuanlan.zhihu.com/p/480293185) > [https://blog.oxings.com/article/31.html](https://link.zhihu.com/?target=https%3A//blog.oxings.com/article/31.html) > [https://blog.csdn.net/best\_luxi/article/details/122543074](https://link.zhihu.com/?target=https%3A//blog.csdn.net/best_luxi/article/details/122543074)
admin
2023年4月19日 06:26
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码