JDK9~11版本和相关特性,建议收藏使用
sinye56 2024-09-29 22:19 7 浏览 0 评论
JDK9(2017.09.21-2018.01.26)
功能特性
1、modularity System 模块系统
2、HTTP/2
3、JShell
4、不可变集合工厂方法
5、私有接口方法
6、HTML5风格的Java帮助文档
7、多版本兼容 JAR
8、统一 JVM 日志
9、java9的垃圾收集机制
10、I/O 流新特性
功能介绍和使用
modularity System 模块系统
Modularity提供了类似于OSGI框架的功能,模块之间存在相互的依赖关系,可以导出一个公共的API,并且隐藏实现的细节,Java提供该功能的主要的动机在于,减少内存的开销,在JVM启动的时候,至少会有30~60MB的内存加载,主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去,模块化可以根据模块的需要加载程序运行需要的class。
在引入了模块系统之后,JDK 被重新组织成 94 个模块。Java 应用可以通过新增的 jlink 工具,创建出只包含所依赖的 JDK 模块的自定义运行时镜像。这样可以极大的减少 Java 运行时环境的大小。使得JDK可以在更小的设备中使用。采用模块化系统的应用程序只需要这些应用程序所需的那部分JDK模块,而非是整个JDK框架了。
HTTP/2
JDK9之前提供HttpURLConnection API来实现Http访问功能,但是这个类基本很少使用,一般都会选择Apache的Http Client,此次在Java 9的版本中引入了一个新的package:java.net.http,里面提供了对Http访问很好的支持,不仅支持Http1.1而且还支持HTTP2(什么是HTTP2?请参见HTTP2的时代来了...),以及WebSocket,据说性能特别好。
JShell
java9引入了jshell这个交互性工具,让Java也可以像脚本语言一样来运行,可以从控制台启动 jshell ,在 jshell 中直接输入表达式并查看其执行结果。当需要测试一个方法的运行效果,或是快速的对表达式进行求值时,jshell 都非常实用。
除了表达式之外,还可以创建 Java 类和方法。jshell 也有基本的代码完成功能。我们在教人们如何编写 Java 的过程中,不再需要解释 “public static void main(String [] args)” 这句废话。
不可变集合工厂方法
Java 9增加了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法来创建不可变集合。
List strs = List.of("Hello", "World");
List strs List.of(1, 2, 3);
Set strs = Set.of("Hello", "World");
Set ints = Set.of(1, 2, 3);
Map maps = Map.of("Hello", 1, "World", 2);
除了更短和更好阅读之外,这些方法也可以避免您选择特定的集合实现。在创建后,继续添加元素到这些集合会导致 “UnsupportedOperationException” 。
私有接口方法
Java 8 为我们提供了接口的默认方法和静态方法,接口也可以包含行为,而不仅仅是方法定义。默认方法和静态方法可以共享接口中的私有方法,因此避免了代码冗余,这也使代码更加清晰。如果私有方法是静态的,那这个方法就属于这个接口的。并且没有静态的私有方法只能被在接口中的实例调用。
HTML5风格的Java帮助文档
Java 8之前的版本生成的Java帮助文档是在HTML 4中。在Java 9中,Javadoc 的输出现在符合兼容 HTML5 标准。现在HTML 4是默认的输出标记语言,但是在之后发布的JDK中,HTML 5将会是默认的输出标记语言。
Java帮助文档还是由三个框架组成的结构构成,这是不会变的,并且以HTML 5输出的Java帮助文档也保持相同的结构。每个 Javadoc 页面都包含有关 JDK 模块类或接口来源的信息。
多版本兼容 JAR
当一个新版本的 Java 出现的时候,你的库用户要花费很长时间才会切换到这个新的版本。这就意味着库要去向后兼容你想要支持的最老的 Java 版本 (许多情况下就是 Java 6 或者 7)。这实际上意味着未来的很长一段时间,你都不能在库中运用 Java 9 所提供的新特性。幸运的是,多版本兼容 JAR 功能能让你创建仅在特定版本的 Java 环境中运行库程序时选择使用的 class 版本
统一 JVM 日志
Java 9 中 ,JVM 有了统一的日志记录系统,可以使用新的命令行选项-Xlog 来控制 JVM 上 所有组件的日志记录。该日志记录系统可以设置输出的日志消息的标签、级别、修饰符和输出目标等。
java9的垃圾收集机制
Java 9 移除了在 Java 8 中 被废弃的垃圾回收器配置组合,同时把G1设为默认的垃圾回收器实现。替代了之前默认使用的Parallel GC,对于这个改变,evens的评论是酱紫的:这项变更是很重要的,因为相对于Parallel来说,G1会在应用线程上做更多的事情,而Parallel几乎没有在应用线程上做任何事情,它基本上完全依赖GC线程完成所有的内存管理。这意味着切换到G1将会为应用线程带来额外的工作,从而直接影响到应用的性能。
I/O 流新特性
java.io.InputStream 中增加了新的方法来读取和复制 InputStream 中包含的数据。
readAllBytes:读取 InputStream 中的所有剩余字节。
readNBytes: 从 InputStream 中读取指定数量的字节到数组中。
transferTo:读取 InputStream 中的全部字节并写入到指定的 OutputStream中。
总结
Jdk9更新的内容比较多,比较关注的是集合接口,流操作这些我们在开发中经常用到。jvm层面日志的优化使得调优方面更加快捷,垃圾回收算到的更改也暗示我们高性能垃圾处理是jdk比较关注的,这些在后面的版本也能得到提现。
JDK10(2018.03.20-2018.07.11)
功能特性
1、局部变量类型推断
2、将JDK森林整合到单个存储库中
3、垃圾收集器接口
4、G1的并行完整GC
5、应用程序类数据共享
6、线程局部握手
7、删除本机头生成工具(javah)
8、其他Unicode语言标签扩展
9、备用内存设备上的堆分配
10、基于Java的实验性JIT编译器
11、根证书
12、基于时间的发行版本控制
功能介绍和使用
1、局部变量类型推断
对于开发者来说,这是 JDK10 唯一的真正特性。它向 Java 中引入在其他语言中很常见的var比如 JavaScript 。只要编译器可以推断此种类型,你不再需要专门声明一个局部变量的类型。一个简单的例子是:
var x = new ArrayList<String>();
这就消除了我们之前必须执行的 ArrayList<String> 类型定义的重复。我鼓励你们去读 JEP ,因为上面有一些关于这个句法是否能用的规则。有趣的是,需要注意 var 不能成为一个关键字,而是一个保留字。这意味着你仍然可以使用 var 作为一个变量,方法或包名,但是现在(尽管我确定你绝不会)你不能再有一个类被调用。
2、将JDK森林整合到单个存储库中
在 JDK9 中,有 8 个仓库: root、corba、hotspot、jaxp、jaxws、jdk、langtools 和 nashorn 。在 JDK10 中这些将被合并为一个,使得跨相互依赖的变更集的存储库运行 atomic commit (原子提交)成为可能。
3、垃圾收集器接口
这不是让开发者用来控制垃圾回收的接口;而是一个在 JVM 源代码中的允许另外的垃圾回收器快速方便的集成的接口。
1、G1的并行完整GC
G1 是设计来作为一种低延时的垃圾回收器(但是如果它跟不上旧的堆碎片产生的提升速率的话,将仍然采用完整压缩集合)。在 JDK9 之前,默认的收集器是并行,吞吐,收集器。为了减少在使用默认的收集器的应用性能配置文件的差异,G1 现在有一个并行完整收集机制。
2、应用程序类数据共享
CDS 在 JDK5 时被引进以改善 JVM 启动的表现,同时减少当多个虚拟机在同一个物理或虚拟的机器上运行时的资源占用。
3、线程局部握手
这是在 JVM 内部相当低级别的更改,现在将允许在不运行全局虚拟机安全点的情况下实现线程回调。这将使得停止单个线程变得可能和便宜,而不是只能启用或停止所有线程。
4、删除本机头生成工具(javah)
Java9 开始了一些对 JDK 的家务管理,这项特性是对它的延续。当编译 JNI 代码时,已不再需要单独的工具来生成头文件,因为这可以通过 javac 完成。在未来的某一时刻,JNI 将会被 Panama 项目的结果取代.
5、其他Unicode语言标签扩展
这将改善 java.util.Locale 类和相关的 API 以实现额外 BCP 47 语言标签的 Unicode 扩展。尤其是,货币类型,一周的第一天,区域覆盖和时区等标签现在将被支持。
6、备用内存设备上的堆分配
硬件技术在持续进化,现在可以使用与传统 DRAM 具有相同接口和类似性能特点的非易失性 RAM 。这项 JEP 将使得 JVM 能够使用适用于不同类型的存储机制的堆。
7、基于Java的实验性JIT编译器
8、根证书
在 JDK 中将提供一套默认的 CA 根证书。关键的安全部件,如 TLS ,在 OpenJDK 构建中将默认有效。这是 Oracle 正在努力确保 OpenJDK 二进制和 Oracle JDK 二进制功能上一样的工作的一部分,是一项有用的补充内容。
12、基于时间的发行版本控制
JDK 版本字符串格式几乎与 JDK 版本一样多。有幸的是,这是最后需要使用到的,我们可以坚持用它。这种格式使用起来很像 JDK9 中介绍的提供一个更加语义的形式。
总结
JDK10版本对开发人员使用而言比较少,这也是JKD版本的常规性迭代。在 1.9、1.10 版本中的主要特性是增加了模块系统,将 G1 设为默认垃圾回收器、支持局部变量推断等功能。这些功能都已经包含在 1.11 版本中。
JDK11(稳定版2017.0921-2018.01.26)
功能特性
JEP 181:基于嵌套的访问控制
JEP 309:动态类文件常量
JEP 315:改进Aarch64内部特性
JEP 318:Epsilon:无操作垃圾收集器
JEP 320:删除Java EE和CORBA模块
JEP 321:HTTP客户端(标准)
JEP 323:本地变量Lambda参数
JEP 324的语法:与Curve25519和Curve448的密钥约定
JEP:Unicode 10
JEP 328:飞行记录器
JEP 329:ChaCha20和Poly1305加密算法
JEP 330:启动单文件源代码程序
JEP 331:低开销堆分析
JEP 332:传输层安全性(TLS)1.3
JEP 333:ZGC:可伸缩的低延迟垃圾收集器(实验性)
335:不推荐使用Nashorn JavaScript引擎
336:不推荐使用Pack200工具和API
功能介绍和使用
JEP 309: Dynamic Class-File Constants(动态类文件常量)
Java的类型文件格式将被拓展,支持一种新的常量池格式:CONSTANTDynamic,加载CONSTANTDynamic会将创建委托给bootstrap方法。其目标是降低开发新形式的可实现类文件约束带来的成本和干扰。
JEP 318:Epsilon:无操作垃圾收集器
JDK上对这个特性的描述是:开发一个处理内存分配但不实现任何实际内存回收机制的GC,一旦可用堆内存用完,JVM就会退出。
如果有System.gc()的调用,实际上什么也不会发生(这种场景下和-XX:+DisableExplicitGC效果一样),因为没有内存回收,这个实现可能会警告用户尝试强制GC是徒劳。
使用如下:
-XX:+UseEpsilonGC
提供完全被动的GC实现,具有有限的分配限制和尽可能低的延迟开销,但代价是内存占用和内存吞吐量。
众所周知,Java实现可广泛选择高度可配置的GC实现。 各种可用的收集器最终满足不同的需求,即使它们的可配置性使它们的功能相交。 有时更容易维护单独的实现,而不是在现有GC实现上堆积另一个配置选项。
它的主要用途如下:
性能测试(它可以帮助过滤掉GC引起的性能假象);
内存压力测试(例如,知道测试用例应该分配不超过1 GB的内存,我们可以使用-Xmx1g配置-XX:+UseEpsilonGC,如果违反了该约束,则会heap dump并崩溃);
非常短的JOB任务(对于这种任务,接受GC清理堆那都是浪费空间);
VM接口测试;
Last-drop 延迟&吞吐改进;
JEP 320:删除Java EE和CORBA模块
Java EE和CORBA两个模块在JDK9中已经标记"deprecated",在JDK11中正式移除。JDK中deprecated的意思是在不建议使用,在未来的release版本会被删除。
JEP 321:HTTP客户端(标准)
将JDK9引进并孵化的HTTP客户端API作为标准,即HTTP/2 Client。它定义了一个全新的实现了HTTP/2和WebSocket的HTTP客户端API,并且可以取代HttpURLConnection。 动机
已经存在的HttpURLConnection有如下问题:
在设计时考虑了多种协议,但是现在几乎所有协议现已不存在。
API早于HTTP/1.1并且太抽象;
使用很不友好;
只能以阻塞模式工作;
JEP 323:本地变量Lambda参数
在Lambda表达式中,可以使用var关键字来标识变量,变量类型由编译器自行推断。局部变量类型推断就是左边的类型直接使用 var 定义,而不用写具体的类型,编译器能根据右边的表达式自动推断类型。
import java.util.Arrays;
public class LocalVar {
public static void main(String[] args) {
Arrays.asList("Java", "Python", "Ruby")
.forEach((var s) -> {
System.out.println("Hello, " + s);
});
}
}
JEP 324的语法:与Curve25519和Curve448的密钥约定
用RFC 7748中描述到的 Curve25519 和Curve448 实现秘钥协议。RFC 7748定义的秘钥协商方案更高效,更安全。这个JEP的主要目标就是为这个标准定义API和实现。
动机
密码学要求使用 Curve25519 和Curve448 是因为它们的安全性和性能。JDK会增加两个新的接口XECPublicKey 和 XECPrivateKey,示例代码如下:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH");
NamedParameterSpec paramSpec = new NamedParameterSpec("X25519");
kpg.initialize(paramSpec);
// equivalent to kpg.initialize(255)
// alternatively: kpg = KeyPairGenerator.getInstance("X25519")
KeyPair kp = kpg.generateKeyPair();
KeyFactory kf = KeyFactory.getInstance("XDH");
BigInteger u = ... XECPublicKeySpec
pubSpec = new XECPublicKeySpec(paramSpec, u);
PublicKey pubKey = kf.generatePublic(pubSpec);
KeyAgreement ka = KeyAgreement.getInstance("XDH");
ka.init(kp.getPrivate());
ka.doPhase(pubKey, true);
byte[] secret = ka.generateSecret();
JEP:Unicode 10
更新平台API支持Unicode 10.0版本(Unicode 10.0概述:Unicode 10.0 增加了8518 个字符, 总计达到了136,690个字符. 并且增加了4个脚本, 总结139个脚本, 同时还有56个新的emoji表情符号。参考:http://unicode.org/versions/Unicode10.0.0/)
JEP 328: 飞行记录器
提供一个低开销的,为了排错Java应用问题,以及JVM问题的数据收集框架,希望达到的目标如下:
提供用于生产和消费数据作为事件的API;
提供缓存机制和二进制数据格式;
允许事件配置和事件过滤;
提供OS,JVM和JDK库的事件;
动机
排错,监控,性能分析是整个开发生命周期必不可少的一部分,但是某些问题只会在大量真实数据压力下才会发生在生产环境。
Flight Recorder记录源自应用程序,JVM和OS的事件。 事件存储在一个文件中,该文件可以附加到错误报告中并由支持工程师进行检查,允许事后分析导致问题的时期内的问题。
JEP 329:ChaCha20 和 Poly1305 加密算法
实现RFC 7539中指定的 ChaCha20 和 ChaCha20-Poly1305 两种加密算法。业界一致认为当下ChaCha20-Poly1305是安全的。
JEP 331:低开销的 Heap Profilin
提供一种低开销的Java堆分配采样方法,得到堆分配的Java对象信息,可通过JVMTI访问。希望达到的目标如下:
足够低的开销,可以默认且一直开启;
能通过定义好的程序接口访问;
能采样所有分配;
能给出生存和死亡的Java对象信息; 动机
对用户来说,了解它们堆里的内存是很重要的需求。目前有一些已经开发的工具,允许用户窥探它们的堆,比如:Java Flight Recorder, jmap, YourKit, 以及VisualVM tools.。但是这工具都有一个很大的缺点:无法得到对象的分配位置。headp dump以及heap histo都没有这个信息,但是这个信息对于调试内存问题至关重要。因为它能告诉开发者,他们的代码发生(尤其是坏的)分配的确切位置。
JEP 332: 支持 TLS 1.3
实现TLS协议1.3版本。(TLS允许客户端和服务端通过互联网以一种防止窃听,篡改以及消息伪造的方式进行通信)
TLS 1.3是TLS协议的重大改进,与以前的版本相比,它提供了显着的安全性和性能改进。其他供应商的几个早期实现已经可用。我们需要支持TLS 1.3以保持竞争力并与最新标准保持同步。这个特性的实现动机和Unicode 10一样,也是紧跟历史潮流。
JEP 333: 可伸缩低延迟垃圾收集器
ZGC:这应该是JDK11最为瞩目的特性,没有之一。但是后面带了Experimental,说明还不建议用到生产环境。看看官方对这个特性的目标描述:
GC暂停时间不会超过10ms;
即能处理几百兆小堆,也能处理几个T的大堆(OMG);
和G1相比,应用吞吐能力不会下降超过15%;
为未来的GC功能和利用colord指针以及Load barriers优化奠定基础;
初始只支持64位系统;
GC是Java主要优势之一。然而,当GC停顿太长,就会开始影响应用的响应时间。消除或者减少GC停顿时长,Java将对更广泛的应用场景是一个更有吸引力的平台。此外,现代系统中可用内存不断增长, 用户和程序员希望JVM能够以高效的方式充分利用这些内存,并且无需长时间的GC暂停时间。 ZGC一个并发,基于region,压缩型的垃圾收集器,只有root扫描阶段会STW,因此GC停顿时间不会随着堆的增长和存活对象的增长而变长。 ZGC和G1停顿时间比较:
ZGC:
avg: 1.091ms (+/-0.215ms)
95th percentile: 1.380ms
99th percentile: 1.512ms
99.9th percentile: 1.663ms
99.99th percentile: 1.681ms
max: 1.681ms
G1 :
avg: 156.806ms (+/-71.126ms)
95th percentile: 316.672ms
99th percentile: 428.095ms
99.9th percentile: 543.846ms
99.99th percentile: 543.846ms
max: 543.846ms
使用:
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
总结
1.11 版本是 Java 最新的长期支持版本,也将会是未来一段时间的主要版本,1.11 版本中提供的最激动人心的功能是 ZGC 这个新的垃圾回收器,ZGC 为大内存堆设计,有着非常强悍的性能,能够实现 10ms 以下的 GC 暂停时间。除此之外,1.11 版本对字符串处理 API 进行了增强,提供了字符复制等功能。1.11 版本还内置了 HttpClient,废弃了一些不安全的工具和API。
接下来将整理jdk12~jdk14的版本特性,欢迎捧场,来过就留下脚印~
相关推荐
- RHEL8和CentOS8怎么重启网络
-
本文主要讲解如何重启RHEL8或者CentOS8网络以及如何解决RHEL8和CentOS8系统的网络管理服务报错,当我们安装好RHEL8或者CentOS8,重启启动网络时,会出现以下报错:...
- Linux 内、外网双网卡路由配置
-
1.路由信息的影响Linux系统中如果有多张网卡的情况下,如果路由信息配置不正确,...
- Linux——centos7修改网卡名
-
修改网卡名这个操作可能平时用不太上,可作为了解。修改网卡默认名从ens33改成eth01.首先修改网卡配置文件名(建议将原配置文件进行备份)...
- CentOS7下修改网卡名称为ethX的操作方法
-
?Linux操作系统的网卡设备的传统命名方式是eth0、eth1、eth2等,而CentOS7提供了不同的命名规则,默认是基于固件、拓扑、位置信息来分配。这样做的优点是命名全自动的、可预知的...
- Linux 网卡名称enss33修改为eth0
-
一、CentOS修改/etc/sysconfig/grub文件(修改前先备份)为GRUB_CMDLINE_LINUX变量增加2个参数(net.ifnames=0biosdevname=0),修改完成...
- CentOS下双网卡绑定,实现带宽飞速
-
方式一1.新建/etc/sysconfig/network-scripts/ifcfg-bond0文件DEVICE=bond0IPADDR=191.3.60.1NETMASK=255.255.2...
- linux 双网卡双网段设置路由转发
-
背景网络情况linux双网卡:网卡A(ens3)和网卡B(...
- Linux-VMware设置网卡保持激活
-
Linux系统只有在激活网卡的状态下才能去连接网络,进行网络通讯。修改配置文件(永久激活网卡)...
- VMware虚拟机三种网络模式
-
01.VMware虚拟机三种网络模式由于linux目前很热门,越来越多的人在学习linux,但是买一台服务放家里来学习,实在是很浪费。那么如何解决这个问题?虚拟机软件是很好的选择,常用的虚拟机软件有v...
- 2023年最新版 linux克隆虚拟机 解决网卡uuid重复问题
-
问题描述1、克隆了虚拟机,两台虚拟机里面的ip以及网卡的uuid都是一样的2、ip好改,但是uuid如何改呢?解决问题1、每台主机应该保证网卡的UUID是唯一的,避免后面网络通信有问题...
- Linux网卡的Vlan配置,你可能不了解的玩法
-
如果服务器上连的交换机端口已经预先设置了TRUNK,并允许特定的VLAN可以通过,那么服务器的网卡在配置时就必须指定所属的VLAN,否则就不通了,这种情形在虚拟化部署时较常见。例如在一个办公环境中,办...
- Centos7 网卡绑定
-
1、切换到指定目录#备份网卡数据cd/etc/sysconfig/network-scriptscpifcfg-enp5s0f0ifcfg-enp5s0f0.bak...
- Linux搭建nginx+keepalived 高可用(主备+双主模式)
-
一:keepalived简介反向代理及负载均衡参考:...
- Linux下Route 路由指令使用详解
-
linuxroute命令用于显示和操作IP路由表。要实现两个不同子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现。在Linux系统中,设置路由通常是为了解决以下问题:该...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)