的更新通常指南-JDK11-JDK17-迈向 (更新包括)
1、前言
上篇文章给大家带来了JDK8更新JDK11的最全通常,置信大家浏览后曾经对JDK11有了比拟深化的了解。2021年9月14日,Oracle颁布了可以常年支持的JDK17版本,那么从JDK11到JDK17,究竟带来了哪些个性呢?亚毫秒级的ZGC成果究竟怎样样呢?值得咱们更新吗?而且更新环节会遇到哪些疑问呢?带着这些疑问,本篇文章将带来完整的JDK11更新JDK17最全通常。
2、为什么更新JDK17
1)常年支持版本
JDK17是Oracle官方在2021年9月14日颁布的一个常年支持(LTS)版本,象征着它将取得常年的更新和支持,有助于坚持程序的稳固性和牢靠性。
2)性能优化
更好的渣滓回收器。综合评价,从8更新到Java11,**G1GC平均速度优化16.1%,ParallelGC为4.5%****,**从Java11更新到Java17, G1GC平均速度优化8.66%,ParallelGC为6.54% (基于OptaPlanner的用例基准测试标明)
最大的亮点是带来了 稳固版的ZGC渣滓回收器,到达亚毫秒级进度。
3)新语法和个性
Switch表白式简化、TextBlocks文本块、instanceof的形式婚配更新和NullPointerException揭示信息改良等
4) 支持最新的技术和框架
Springframework6和SpringBoot3都自动经常使用Java17作为最低版本
3、更新后压测成果
我在JDOS平台上选用了不同性能的机器(2C4G、4C8G、8C16G),并区分经常使用JDK8、JDK11和JDK17启动部署和压测。
整个压测环节限时60分钟,用180个虚构用户并发恳求一个接口,每次接口恳求都创立512Kb的数据。最终产出不同GC回收器的各名目的数据,来剖析GC的性能优化成果。
以下是压测的性能状况:
4、OracleJDK和OpenJDK的选用
2021年9月,Oracle发表JDK17可以收费商用,直到下一个LTS版本之后继续提供整整一年,同时Oracle将继续依照自Java9以来的相反版本和期间表提供GPL下的OracleOpenJDK版本。
2023年9月,OracleJDK颁布了新的LTS版本JDK21,这就象征着从 2024年9月开局,在消费环境经常使用OracleJDK17将须要付费。
参考:
OracleJDK和OpenJDK这两个之间没有真正的技术差异,由于针对OracleJDK构建环节是基于OpenJDK的。自从JDK11开局,OracleJDK和OpenJDK在性能上基本相反,所以介绍经常使用OpenJDK17或其余开源的JDK版本,这些开源版本都是基于OpenJDK构建并提供常年支持的,比如:AdoptOpenJDK、RedHatOpenJDK。
官方参考:
5、JDK11到JDK17带来了哪些新个性
5.1、JVM改良
1、ZGC渣滓回收器从试验性性能更改为 正式产品性能 ,从JDK11引入以来,经过继续的迭代更新,目前曾经足够稳固。 须要手动开启,开启形式:-XX:+UseZGC
2、G1渣滓回收器依然作为自动渣滓回收器,启动改良更新,关键包含可停止的混合搜集汇合、NUMA可识别内存调配等
3、JDK14开局删除CMS渣滓回收器
4、JDK14开局弃用ParallelScavenge和SerialOldGC的组合经常使用
5、JDK15禁用倾向锁,自动禁用:-XX:+UseBiasedLocking
6、NullPointerException揭示信息改良
JDK14以前的产生NullPointerException时,只能定位到所在意外行,无法定位详细是哪个变量。改良后的NullPointerException,可以明晰形容详细变量,优化了空指针意外的可读性。
5.2、新语法个性
5.2.1、Switch表白式简化
switch表白式带来了简化式的编码形式,提供了新的分支切换形式,即->符号,右则表白式方法体在口头完分支方法之后,智能完结switch分支,同时->右则方法块中可以是表白式、代码块或许是手动抛出的意外
参考:
传统写法
新写法
5.2.2、TextBlocks文本块
参考:
经过编写""",来缩小转义字符和换行符,到达简化代码和提高代码可读性的目的
5.2.3、Record类型
参考:
record是JDK14引入的关键字,用于申明无法变的数据类。它适用于存储纯正的值类型数据,如接口传输数据、坐标点和只读的日志记载。与lombok相比,record简化了定义纯正数据类型的环节。由于record类是无法变的,成员变量只能设置一次性且无法更改,无需提供显式的setter()方法。
1、定义Point类,经常使用关键字record,未定义get/set
2、检查编译后的字节码文件
3、经常使用Point类
5.2.4、instanceof的形式婚配更新
参考:
5.2.5、密封的类和接口
参考:
JDK15开局,引入了sealed个别类或接口类,这些类只准许被指定的类或许interface启动裁减和成功。
经常使用润色符sealed,您可以将一个类申明为密封类。密封的类经常使用关键字permits列出可以间接裁减它的类。子类可以是最终的,非密封的或密封的
比拟适用的一个个性,可以用来限度类的档次结构
5.2.6、其余优化和更新
感兴味的同窗,介绍浏览OpenJDK官方文档说明,从JDK11到JDK17的改变:
6、更新步骤
6.1、JDK选用
OpenJDK17下载:
行云镜像:jdt-base-/java-jdt-7.4-openjdk-17.0.2-tomcat8.0.53
6.2、pom编译性能更新
maven编译所需JDK更新至17
6.3、SpringBoot更新
SpringBoot版本更新到,Spring版本更新为
为什么不更新到SpringBoot3?
SpringBoot3.0最低要求Java17,SpringBoot3.0带来了很多变动,和SpringBoot2差异较大。思考到公司很多两边件都是基于SpringBoot2构建的,所以此处介绍更新到SpringBoot2的最高版本2.7.15。
POM更新
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
也可以经过设置dependencyManagement的形式:
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${springboot-version}</version>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${springframework.version}</version>
参考:
spring更新指南:
springboot版本官方:
循环依赖疑问
SpringBoot更新到2.7.15后,假设运行中存在循环依赖的疑问,启动时会报如下失误:
要素 :官方文档不激励循环依赖援用,自动状况下是制止的
处置打算:
第一种:介绍更新运行中bean的依赖相关来处置
第二种:性能文件中参与以下性能, 为了和旧版本坚持分歧,此性能介绍参与
#开放循环依赖
spring.mn.allow-circular-references=true
6.4、罕用两边件更新
6.4.1、Lombok版本更新到1.18.20以上
<groupId>org.projectlombok</groupId>
假设不更新,编译时会报错如下:
6.4.2、swgger疑问,springfox3.0.0和springboot2.7版本不兼容
意外:
Failedtostartbean'documentationPluginsBootstrer';nestedexceptionisjava.lang.NullPointerException:
Cannotinvoke"org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()"because"this.condition"isnull
处置打算:
*参与如下性能可处置SpringBoot2.7.15与Swagger3.0.0不兼容疑问
publicBeanPostProcessorspringfoxHandlerProviderBeanPostProcessor(){
returnnewBeanPostProcessor(){
publicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{
if(beaninstanceofWebMvcRequestHandlerProvider||beaninstanceofWebFluxRequestHandlerProvider){
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
returnbean;
private<TextendsRequestMappingInfoHandlerMapping>voidcustomizeSpringfoxHandlerMappings(List<T>mappings){
List<T>copy=mappings.stream().filter(mapping->mapping.getPatternParser()==null).collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
@SuppressWarnings("unchecked")
privateList<RequestMappingInfoHandlerMapping>getHandlerMappings(Objectbean){
Fieldfield=ReflectionUtils.findField(bean.getClass(),"handlerMappings");
field.setAccessible(true);
return(List<RequestMappingInfoHandlerMapping>)field.get(bean);
}catch(IllegalArgumentException|IllegalAccessExceptione){
thrownewIllegalStateException(e);
参考:
6.4.3、AKS更新(针对间接从JDK8更新的状况)
意外 :Causedby:java.lang.NoClassDefFoundError:javax/xml/bind/JAXBException
要素 :Java11删除了JavaEEmodules,其中就包含java.xml.bind(JAXB)。
处置打算:
手动引入如下包即可
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
6.4.4、Concrete性能中心阻塞更新
经常使用Concrete时,启动时意外:
Unabletomakefieldprivatestaticfinaljava.lang.reflect.Methodjdk.proxy2.$Proxy97.m0accessible:
modulejdk.proxy2doesnot"opensjdk.proxy2"tounnamedmodule@61d47554
要素:
剖析下Concrete报错的要素,如下图,包内com.wangyin.concrete.spring.ConcreteConfigProcessor#postProcessAfterInitialization(212行)的成功逻辑
处置打算:
1、在JVM启动参数中设置--add-opensjdk.proxy2来开启私有字段的访问,但由于灵活代理生成的包名是随机不明白的, 所以这种打算无法行 。JDK官方文档也明白示意不支持访问灵活代理外部的随机字段。官方说明:~mr/jigsaw/spec/api/java/lang/reflect/Proxy.
2、代码修正,只有把f.setAccessible(true)移到Modifier.isStatic(f.getModifiers())的判别下方即可。要素是方法Modifier.isStatic(f.getModifiers())原本就要跳过静态字段,这样修正间接防止了访问。 推进concrete团队修复疑问或改换经常使用Ducc性能中心
6.5、JVM启动参数性能
6.5.1、开启ZGC
启动参数中性能: -XX:+UseZGC
移除-XX:ConcGCThreads,行云部署下JVM参数性能须要肃清
6.5.2、不同两边件所需启动参数
更新JDK17后,名目启动时或许会遇到如下两种类型的意外:
1、cannotaccessclasssun.util.calendar.ZoneInfo(inmodulejava.base)because modulejava.base doesnot exportsun.util.calendar tounnamedmodule@0x2611f533
2、Unabletomakefieldfinalintjava.math.BigInteger.signumaccessible: modulejava.base doesnot" opensjava.math "tounnamedmodule@525f1e4e
意外要素:
自从JDK9中引入了模块化性能后,再到JDK17,关于包扫描和反射的权限控制愈加的严厉。经常出现的库比如(Spring)少量用到包扫描和反射,所以常产生此失误。
处置打算:
一个粗犷的处置方法是将没开明的module强迫对外开明,即坚持和Java9之前的版本分歧。
关键区别在于--add-opens准许深度反射,即非公共成员的访问,才可以调用setAccessible(true)
参考:
SGM须要参与:
--add-opensjava.management/java.lang.management=ALL-UNNAMED
--add-opensjdk.management/com.sun.management.internal=ALL-UNNAMED
--add-opensjava.management/sun.management=ALL-UNNAMED
R2M须要参与:
--add-opensjava.base/java.time=ALL-UNNAMED
Ducc须要参与:
--add-opensjava.base/java.util.concurrent=ALL-UNNAMED
--add-opensjava.base/java.util.concurrent.locks=ALL-UNNAMED
--add-opensjava.base/java.security=ALL-UNNAMED
--add-opensjava.base/jdk.internal.loader=ALL-UNNAMED
--add-opensjava.management/com.sun.jmx.mbeanserver=ALL-UNNAMED
--add-opensjava.base/java.net=ALL-UNNAMED
--add-opensjava.base/sun.nio.ch=ALL-UNNAMED
AKS须要参与:
--add-exportsjava.base/sun.security.action=ALL-UNNAMED
--add-opensjava.base/java.lang=ALL-UNNAMED
--add-opensjava.base/java.math=ALL-UNNAMED
--add-opensjava.base/java.util=ALL-UNNAMED
--add-opensjava.base/sun.util.calendar=ALL-UNNAMED
6.6、启动后的验证
1.介绍先更新JDK11,再到JDK17,一边更新一边启动验证观察
2.观察日志能否无心外,特意是下面说到的启动时意外
3.观察监控类软件,比如SGM、UMP等监控能否反常
4.介绍逐渐有序切量,并做好常态化压测,防止影响外围业务
5.更新成功后, 最好能做个全流程的性能测试,防止性能意外
7、总结
假设还逗留在JDK8,介绍先更新JDK11,再到JDK17,详细更新步骤先参考我的上篇文章JDK8更新JDK11最全通常干货来了,再参考本章中的更新步骤。
宿愿以上分享可以给大家带来实践的协助,更新环节中假设遇到疑问,欢迎大家在评论区回复。
Java JDK下载与安装超详细教程,附图片讲解!
JavaJDK下载与安装超详细教程如下:
目前JDK的版本分为non-LTS短期维护和LTS长期维护两种情况。建议大家下载LTS版本的JDK。而目前最主流的LTS版本还是JDK8,所以本文的教程主要是基于JDK8环境。如果你想体验新版JDK,可以下载JDK11或JDK17,不要下载安装其他的non-LTS版本。
1、下载方法
在JDK官网选择需要的版本下载即可。
2、注意事项
如果你之前没有在Oracle官网注册过账号,有可能需要先注册登录。然后可以根据自己电脑的CPU型号,选择点击(32位),或者是(64位)进行下载。
这里的8u341代表JDK8版本,341代表子版本,u是update(更新)的缩写。另外Windowsi586对应的是Windows32位系统,Windows x 64对应的是Windows64位系统。
安装JDK和JRE的详细步骤
1、双击安装包
下载完jdk安装包之后,【双击】“”文件,然后点击【下一步】:
2、自定义安装目录
DK的默认安装目录为“C:\ProgramFiles(x86)\Java\jdk1.8.0_221\”,建议大家更改一下安装目录,最好不要安装在C盘下,防止以后重装系统后还需要重新安装JDK。
你可以通过点击【更改】按钮,自定义安装路径,我这里把JDK安装到了D盘的一个路径下。
特别提示:从你学习编程开始,请养成一个良好的习惯,不要使用中文或特殊字符(包括空格)作为文件夹的名称,否则后期开发时可能出现一些莫名其妙的错误。
3、等待安装完成
继续点击【下一步】按钮,会出现“正在安装......正在复制新文件”的界面,等待安装结束,JDK就算是安装完毕了。
在成功地安装好JDK之后,就可以在自己的安装目录下看到JDK文件夹,一般如下图所示:
JDK安装目录下的bin(binary)文件夹,是二进制命令文件所在的目录,其中有各种exe文件(都是使用java语言编写),就是我们开发Java程序时所需要的命令工具。
这些命令文件一般都不是以图形化方式操作的(双击执行无效),而是以命令行的方式操作的,所以我们使用时一般都是要在命令行窗口中进行操作。其中比较常用的命令有、、等。
友情提示:
其实JDK并不需要每次都安装,因为它本身是绿色版本,我们其实可以直接把JDK安装存入到自己的U盘,这样你在任何计算机上都可以直接使用。
但绝大多数情况下,我们还是采用安装到电脑上的方式来使用JDK。这样做的好处在于,JDK会在注册表中被注册,这样以后JDK出现新版本时会自动更新。
接下来系统界面会提示你,是否需要再选择安装一个额外的JRE。这是可选的,因为之前安装的JDK中,已经包含了开发环境和JRE运行环境两部分,所以不必再安装一个JRE。一般情况下,我们直接点击【取消】按钮即可。
但如果你没有点击【取消】按钮,而是点击了【下一步】按钮,也是可以的,在我们点击了【下一步】按钮之后,就会出现如下界面:
最后点击【关闭】按钮,额外的JRE也就安装完毕了。
Java11的新功能有哪些
Java 11 JDK中已计划的新功能目前来看,JDK 11已有九个已经确认的新功能,而且还有更多新功能仍在考虑之中。 计划的新功能包括:HTTP客户端(标准),这个功能于JDK 9中引入并在JDK 10中得到了更新,现在终于转正了。 该API通过CompleteableFutures提供非阻塞请求和响应语义,可以联合使用以触发相应的动作。 自从JDK 9和10中引入该功能后,JDK 11完全重写了该功能,现在其实现完全是异步的。 RX Flow的概念也得到了实现,这样就无需为了支持HTTP/2而创造许多概念了。 现在,在用户层请求发布者和响应发布者与底层套接字之间追踪数据流更容易了。 这降低了复杂性,并最大程度上提高了HTTP/1和HTTP/2之间的重用的可能性。 Epsilon废品回收器,被称为“no-op”回收器,它仅负责内存分配,却没有实现任何实际的内存回收机制。 Epsilon回收器可以用于性能测试、内存压力测试和虚拟机接口。 它还可以用于短生命周期的任务。 lambda参数的局部变量语法,可以消除隐含类型表达式中正式参数定义的语法与局部变量定义语法的不一致。 这样就能在隐含类型的lambda表达式中定义正式参数时使用var了。 Java的类文件格式将被扩展,以支持新的常量池,CONSTANT_Dynamic。 其目标是降低开发新形式的可实现类文件约束带来的成本和干扰。 采用Curve和Curve448加密的密钥交换比现有的Diffie-Hellman椭圆曲线密钥交换方式更有效、更安全。 根据IETF的资料,Curve和Curve448两种椭圆曲线采用常量时间的实现方式,以及不会发生异常的数乘实现,能更好地抵抗各种旁路攻击,包括时序攻击、缓存攻击等。 该提案的目标是为密钥交换方法提供一个API和实现,同时开发一个平台无关、纯Java的的实现。 由于该提案采用了复杂且精密的模算数,因此还是有风险的。 飞行记录仪(Flight Recorder)将提供低开销的数据收集框架,用来调试Java应用程序和HotSpot JVM。 飞行记录仪是Oracle的商业版JDK的功能,但在JDK 11中,其代码将移动到公开代码库中,这样所有人都能使用该功能了。 Iclouded将作为API,以事件的形式产生或消耗数据,同时提供缓存机制、二进制数据工具,同时支持配置和事件过滤。 该提案还提议为OS、HotSpot和JDK库提供事件。 更新platform API以支持Unicode版本10.0,从而使Java跟上潮流。 预计以下的类将支持:lang包中的Character和包中的NumericShapertext包中的Bidi、BreakIterator和Normalizer实现ChaCha20和Poly1305加密算法。 ChaCha20是种相对较新的流加密算法,能代替旧的、不安全的R4流加密。 ChaCha20将与Poly1305认证算法配对使用。 ChaCha20和ChaCha20-Poly1305加密实现将通过 API于SunJCE(Java加密扩展)中提供。 增强Java启动器,使之能够运行单一文件的Java源代码,使得应用程序可以直接从源代码运行。 单文件程序常见于小型工具,或开发者初学Java时使用。 而且,单一源代码文件有可能会编译成多个类文件,这会增加打包开销。 由于这些原因,在运行程序之前进行编译,已成为了不必要的步骤。 Java JDK 11仍在开发中的新功能Java 11的创建者们还在考虑几个对JDK 11的变更或新功能的提案:给Java添加raw字符串字面值。 这样可以更容易地以人类可阅读的形式书写字符序列,而无需特殊的Java标记。 这样也能更容易地将非Java语法的字符串提供给Java使用,还能支持多行字符串,而无需使用特殊的标记。 扩展switch语句,使之能作为语句或表达式使用。 这样还能改进switch处理null值的方式。 这些改动可以简化编程,同时为switch支持模式匹配做准备。 嵌套的访问控制,对应于Java当前的嵌套类型。 嵌套可以让逻辑上属于同一代码实体但被编译到不同的类文件中的类互相访问对方的私有成员,而无需让编译器插入扩大访问权限的方法。 JDK 11删除的功能Java EE和CORBA模块从Java SE9就成了不推荐使用(deprecated),并计划在未来的版本中删除。 这个未来版本就是JDK 11。 Java SE 6于2006年12越发布,它为Java EE平台提供了整套的Web服务技术栈:JAX-WS(Java API for XML-based Web Services),JAXB(Java Architecture for XML Binding),JAF(JavaBeans Activation Framework),以及Common Annotations for Java。 这些年来,Java EE版本在不断进化,这给Java SE造成了许多麻烦,例如加入与Java SE无关的技术,以及同时维护两个Java版本的困难变得更大。 由于独立的Java EE版本由第三方网站提供,Oracle说Java SE或JDK中已经没有必要提供Java EE了。 当然,一些依赖于JDK中的Java EE API及工具的应用程序将无法编译或运行。 将JDK 6、7或8移植到新版本时将会产生二进制不兼容和源代码不兼容。 Oracle说,受到这些影响的开发者可以部署相应的Java EE版本。 CORBA来自于二十世纪九十年代,Oracle说,现在用CORBA开发现代Java应用程序已经没有意义了,维护CORBA的成本已经超过了保留它带来的好处。 但是删除CORBA将使得那些依赖于JDK提供部分CORBA API的CORBA实现无法运行。 目前还没有第三方CORBA版本,也不确定是否会有第三方愿意接手CORBA API的维护工作。 JavaFX已经被移除,因此已经与Java JDK每年两次的更新无关。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。