转载

Java 12 特性冻结,但原始字符串字面量特性被移除

JDK 12 是 Java SE 的下一个版本,已经到了版本发布流程的第一个减速点(ramp-down point),该版本的特性已被冻结。 JDK 12 提供了增强的 switch 语句的预览,为 G1 垃圾回收器添加了许多改进,并新引入了一个名为 Shenandoah 的实验性垃圾回收器。

但是,JDK 12 主要提案之一的原始字符串字面量(raw string literals)却被从这个版本移除了。 根据 JEP,“原始字符串字面量可以跨多行源代码,并且里面的转义串不会被解析,例如/ n,或者像/ uXXXX 形式的 Unicode 转义”。 所以,你不再需要这样写:

复制代码

String html ="<html>/n"+
" <body>/n"+
" <p>Hello World.</p>/n"+
" </body>/n"+
"</html>/n";

而是应该写成下面这样:

复制代码

String html = '<html>
<body>
<p>Hello World.</p>
</body>
</html>
';

“…我们认为基于当前的状态提供预览会对 Java 语言不利”,Brian Goetz 在一封电子邮件中写道:

我们当然感到失望,因为这意味着这个特性需要更长一点时间才能变成 Java 语言的一部分,但我们认为这是最佳选择。

虽然我们可以预料到,任何语言特性都会收到大量诸如“我更希望它不是这样的”的反馈,在我们审查收到的反馈时,我不再确信我们在复杂性和表现力(expressiveness)之间作出了正确的权衡,或者说我不确信我们已经对所有可能的设计进行了足够的探索,以确保当前的方案是我们能做出的最优方案。 通过移除这个特性,我们可以继续完善设计,探索更多选项,以便可以提供一个能满足预览特性流程(Preview Feature process,JEP 12)要求的预览。

就已添加的新特性而言,我们前面提到的 JEP 325:Switch Expressions 是 JDK 12 的一个预览特性。 在这个 JEP 中,Java switch 语句有两个主要变化。 一个变化是新的 switch 书写形式,写成“case L - >”表示如果标签匹配成功,则只执行标签右侧的代码:

复制代码

switch(day) {
caseMONDAY, FRIDAY, SUNDAY -> System.out.println(6);
caseTUESDAY -> System.out.println(7);
caseTHURSDAY, SATURDAY -> System.out.println(8);
caseWEDNESDAY -> System.out.println(9);
}

另一个变化是 switch 可以成为一个表达式,因此它可以有值,或者它可以返回一个值:

复制代码

T result = switch (arg) {
case L1 -> e1;
case L2 -> e2;
default-> e3;
};

JDK 12 还对 G1 垃圾回收器进行了一些重要的增强。 G1 的目标之一是当回收器造成停顿时,能达到用户指定的停顿时间目标。但在某些情况下,回收器可能无法达到这个目标。 发生这种情况是因为 G1 使用一组启发式算法来选择在收集期间要做的工作,这些工作被称为收集集合(collection set)。目前,G1 需要从所有收集集合区域中收集所有活动对象,并且在此过程中不能停止。 因此,如果回收器的启发式算法选择了过大的收集集合,回收器可能会超出暂停目标。选择过大的收集集合这种情况是可能发生的,比如应用程序行为发生了改变而启发式算法仍然工作在“旧”数据上。

为了达到用户提供的停顿时间目标,JEP 344 通过把要被回收的区域集(混合收集集合)拆分为强制和可选部分,使 G1 垃圾回收器能中止垃圾回收过程。 G1 可以中止可选部分的回收以达到停顿时间目标。

G1 的另一个问题是它并不总是及时地将已提交(committed)的 Java 堆内存返还给操作系统,因为 G1 只在完整 GC 或并发周期内从 Java 堆返还内存。 JEP 346 指出:

由于 G1 尽量避免完整的 GC,并且仅基于 Java 堆占用和分配活动来触发并发周期,因此在许多情况下,除非从外部强制执行,否则它不会返还 Java 堆内存。

在资源需要付费使用的容器环境中,这种行为对客户尤其不利。

该 JEP 的既定目标是增强 G1 垃圾回收器,使其在空闲时自动将 Java 堆内存返还给操作系统。

除了对 G1 的增强之外,JDK 12 还增加了一个名为 Shenandoah 的新的实验性垃圾回收器,它在 Java 线程运行的同时进行转移 (evacuation) 工作来减少停顿时间。

Shenandoah 由 Red Hat 开发。 它是一个标记 / 复制回收器,在许多方面与 G1 类似。 主要区别在于回收器在转移阶段使用 Brooks 前向(forwarding)指针。 其想法是堆上的每个对象都有一个额外的引用字段。 该字段初始时指向对象本身,一旦对象被复制到新位置,它就指向新位置。 这使得它可以在应用线程执行的同时转移对象。

Shenandoah 的停顿时间与堆大小无关,但回收器会带来性能损失,因此它对于堆较大的应用程序更有用。 论文 PPPJ2016 对该算法进行了深入描述。

JDK 12 的其它新特性包括:

  • JEP 334:提出一个 API 来对关键类文件 (key class-file) 和运行时构件(artefact)的名义描述 (nominal description) 进行建模,特别是那些可以从常量池加载的常量。该 API 的草案可在此处获得。

  • JEP 230:一套微基准测试,可以基于 Java Microbenchmark Harness(JMH)轻松测试 JDK 的性能。

  • JEP 340:JDK 中针对 ARM 64-bit 有两套不同的源码(即移植)。一套是 arm64,来自 Oracle;另一套是 aarch64。该 JEP 将删除与 arm64 port 相关的所有源码,同时保留 32 位 ARM 移植和 64 位 aarch64 移植。

  • JEP 341:类数据共享(Class Data-Sharing,CDS)是一项减少启动时间的特性。JEP 提到,由于共享,运行 HelloWorld 的启动时间缩短了 32%。但是,若想利用类数据共享,用户必须额外运行一步 java -Xshare:dump,即使使用 JDK 中默认提供的类也不例外。使用该 JEP,默认将生成类数据共享存档。

JDK 12 的候选发布版本预计将在 2 月初发布,GA 版本将于 3 月中旬发布。

查看英文原文:

https://www.infoq.com/news/2018/12/jdk-12-new-features

原文  https://www.infoq.cn/article/r1z8U*lIhw64KVbalWPP
正文到此结束
Loading...