JDK10要来了:下一代 Java 有哪些新特性?

时间:2022-05-06
本文章向大家介绍JDK10要来了:下一代 Java 有哪些新特性?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

JDK 10 目前正在Rampdown Phase One,开发正在努力的修复着bug。

排期

2017/12/14

Rampdown Phase One

2018/01/11

All Tests Run

2018/01/18

Rampdown Phase Two

2018/02/08

Initial Release Candidate

2018/02/22

Final Release Candidate

2018/03/20

General Availability

新增功能点:

286: 类型推断

296: 将JDK合并到单个代码库中

304: 垃圾收集器接口(Garbage-Collector Interface)

307: G1的Full GC实现并行(Parallel)

310: 应用程序类数据共享(Application Class-Data Sharing)

312: 线程局部握手(Thread-Local Handshakes )

313: 干掉javah

314: 增强的Unicode语言标签扩展

316: 支持在可替代的内存设备上进行堆分配

317: 基于Java的实验性JIT编译器(Experimental Java-Based JIT Compiler )

319: 根证书

322: 基于时间(Time-Based)的版本控制模型

好,来详细看看每个功能点吧。

286 类型推断

以后你可以像写js一样这样写java代码了:

var list = new ArrayList<String>(); // infers ArrayList<String> var stream = list.stream(); // infers Stream<String>

296: 将JDK合并到单个代码库中

JDK 9的时候,由分成很多个代码库来开发,有8个之多:root, corba, hotspot, jaxp, jaxws, jdk, langtools, and nashorn。

从JDK10开始,所有的代码库合并成了一个库。一个目的,就是为了简化开发!

304: 垃圾收集器接口(Garbage-Collector Interface)

在jdk10以前,各个gc的实现都是放在src/hotspot/share/gc/$NAME下,$NAME就是具体的gc名称,比如 G1就被放在src/hotspot/share/gc/g1, CMS 就被放在src/hotspot/share/gc/cms, 等等。

然而,还有一些和gc相关的代码却散步在其他的代码中,而不是放在上面对应的目录中。 例如,大多数GC需要一定的障碍(barriers),这个barrier是需要在运行时,解释器(intercepter),C1和C2中实现。 这些屏障并不包含在GC的特定目录中,而是在共享的解释器,C1和C2的源代码(是一个长长的if else链)中实现的。 同样的问题还出现在MemoryMXBean等诊断代码中。

jdk的开发大大们认为这样的情况有如下缺点:

对于GC开发者来说,实现一个新的垃圾收集器需要了解所有这些不同的地方,以及如何扩展它们来满足他们的特定需求。

对于不是GC开发人员的HotSpot开发人员来说,在给定的GC中找到一段特定的代码是令人痛苦的。

在构建时,很难排除特定的垃圾收集器。 #define INCLUDE_ALL_GCS 长期以来只是内置串行收集器来构建JVM,但是这种机制变得太不灵活了。

嗯,很烦,沟通起来费劲,没有统一的接口,也不灵活。现在是时候改变了。

干净的GC接口将使实现新的收集器变得更容易,这将使代码更加清洁,并且在构建时可以更简单地排除一个或多个收集器。 添加一个新的垃圾收集器只需要一个实现一套完善的文档接口的问题,而不是搞清楚HotSpot中所有需要改变的地方。

307: G1的Full GC实现并行(Parallel)

在JDK 9中,G1垃圾收集器是默认的。以前的默认并行收集器(parallel collector)full gc是并行的。既然是这样,那么G1的收集也应该是并行的才对。在JDK10中gc就是并行的了。

310: 应用程序类数据共享(Application Class-Data Sharing)

应用程序数据共享,通过跨进程共享通用类的元数据,减少空间占用及启动时长。

四个目的:

  1. 通过在不同的Java进程间共享公共类元数据来减少占用空间。
  2. 改善启动时间。
  3. 扩展CDS以允许来自JDK运行时映像文件(比如,$ JAVA_HOME / lib / modules)的归档类(archived classes)和应用程序class path加载到内置平台和系统类加载器(system class loader)中。
  4. 扩展CDS以允许将打包的classes加载到自定义class loader中。

312: 线程局部握手(Thread-Local Handshakes )

线程本地握手,不执行全局VM安全点也能对线程执行回调,同时实现单线程停止回调。利用所谓的非对称Dekker同步技术,通过与Java线程握手来消除一些内存障碍(memory barrier)。现在实现同步连内存屏障都不用了,直接使用了Dekker算法。

总之,Handshakes和普通的safepoint机制有所不同,是不一般的safepoint,具体有多叼,还请观看下面这段官方的描述:

A handshake operation is a callback that is executed for each JavaThread while that thread is in a safepoint safe state. The callback is executed either by the thread itself or by the VM thread while keeping the thread in a blocked state. The big difference between safepointing and handshaking is that the per thread operation will be performed on all threads as soon as possible and they will continue to execute as soon as it’s own operation is completed. If a JavaThread is known to be running, then a handshake can be performed with that single JavaThread as well. In the initial implementation there will be a limitation of at most one handshake operation in flight at a given time. The operation can, however, involve any subset of all JavaThreads. The VM thread will coordinate the handshake operation through a VM operation which will in effect prevent global safepoints from occurring during the handshake operation. The current safepointing scheme is modified to perform an indirection through a per-thread pointer which will allow a single thread's execution to be forced to trap on the guard page. Essentially, at all times there will be two polling pages: One which is always guarded, and one which is always unguarded. In order to force a thread to yield, the VM updates the per-thread pointer for the corresponding thread to point to the guarded page. Thread-local handshakes will be implemented initially on x64 and SPARC. Other platforms will fall back to normal safepoints. A new product option, -XX:ThreadLocalHandshakes (default value true), allows users to select normal safepoints on supported platforms.

313: 干掉javah

把javah 从 JDK中干掉了。

该工具已被JDK 8(JDK-7150368)中添加的javac中的新功能所取代。 此功能可以在编译Java源代码时自动添加native的头文件,现在放进了javac中,所以这个功能就被砍掉了,不再单独提供了。

314: 增强的Unicode语言标签扩展

增强java.util.Locale和相关API以实现BCP 47语言标签(tags)的附加Unicode扩展。

目的

支持BCP 47语言标记最初是在Java SE 7中添加的,支持Unicode区域扩展限于日历和数字。 此JEP将在相关的JDK类中实现更多的最新LDML规范中指定的扩展。

316: 支持在可替代的内存设备上进行堆分配

从jdk10开始,使HotSpot虚拟机支持在用户指定的备用内存设备(如NV-DIMM)上分配Java对象堆。

目的

随着便宜的NV-DIMM内存的普及,未来的系统可能配备异构内存架构。这种技术的一个例子是英特尔的3D XPoint。除DRAM之外,这样的架构将具有一种或多种具有不同特性的非DRAM存储器。

这个JEP针对与DRAM具有相同语义的替代存储器设备,包括原子操作的语义,因此可以代替DRAM用于对象堆而不改变现有的应用程序代码。所有其他的内存结构,如代码堆,元代码空间,线程堆栈等,都将继续驻留在DRAM中。

666

使用场景:

在多JVM部署中,一些JVM(如守护进程,服务等)的优先级低于其他JVM。与DRAM相比,NV-DIMM可能具有更高的访问延迟。低优先级进程可以使用NV-DIMM内存作为堆,允许高优先级进程使用更多的DRAM。

大数据和内存数据库等应用程序对内存的需求不断增加。这种应用可以使用NV-DIMM作为堆,因为与DRAM相比,NV-DIMM有更大的容量,成本更低。

317: Java-BasedJIT编译器(Experimental Java-Based JIT Compiler )

启用基于Java语言的JIT编译器Graal,将其用作Linux / x64平台上的实验性JIT编译器。注意:是Experimental,还不是正式的。

目的

基于Java的JIT编译器Graal是JDK 9中引入的实验性AOT(Ahead-of-Time) 编译器的基础。

描述

使Graal可以用作实验JIT编译器,在Linux / x64平台上。 Graal将使用JDK 9中引入的JVM编译器接口(JVMCI)。Graal已经在JDK中,因此将它作为一个实验JIT将主要用于测试和调试工作。

要启用Graal作为JIT编译器,请在java命令行上使用以下选项:

-XX:+ UnlockExperimentalVMOptions -XX:+ UseJVMCICompiler

319: 根证书

在JDK中提供一组默认的根证书颁发机构(CA)证书。

在Oracle的Java SE根CA程序中开源获取根证书,以使OpenJDK对开发人员更具吸引力,并减少OpenJDK构建与Oracle JDK构建之间的差异。

322: 基于时间(Time-based)的版本控制模型

修改Java SE平台和JDK的版本字符串方案以及相关的版本信息,以用于当前和未来的基于时间的版本模型。

基于时间序列的版本管理模型长这样:

$ java --version openjdk 10.0.1 2018-04-19 OpenJDK Runtime Environment (build 10.0.1+13) OpenJDK 64-Bit Server VM (build 10.0.1+13, mixed mode) $

发现没,和之前的相比多了个时间:

java version "1.8.0_102" Java(TM) SE Runtime Environment (build 1.8.0_102-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

怎么感觉jdk 9 要变成 windows的vista了。