JDK12
低暂停时间垃圾收集器(实验性)
Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)
添加一个名为Shenandoah的新垃圾收集(GC)算法,通过与正在运行的Java线程同时进行疏散工作
来减少GC暂停时间。使用Shenandoah的暂停时间与堆大小无关,这意味着无论堆是200MB还是200GB,都
将具有相同的一致暂停时间。
Zing/Azul有一个pauseless收集器,但是这个工作并没有贡献给OpenJDK。
ZGC有一个基于彩色指针的低暂停收集器。 我们期待着比较两种策略的表现。
G1做一些并行和并发的工作,但不做并发疏散。
CMS做并发标记,但它在暂停时间执行年轻代复制,并且从不压缩老代。 这将导致在老一代中花费更多时间来管理空闲空间以及碎片化问题。
微基准测试
在JDK源代码中添加一套基本的微基准测试,使开发人员可以轻松运行现有的微基准测试并创
建新的基准测试
Switch表达式(预览版)
这是JEP 325提出的一个预览版本的预发特性。现在被JDK13的 JEP 354替代了。扩展了switch语法,可以用作语句或表达式。
老的写法:
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
System.out.println(6);
break;
case TUESDAY:
System.out.println(7);
break;
case THURSDAY:
case SATURDAY:
System.out.println(8);
break;
case WEDNESDAY:
System.out.println(9);
break;
}
新的写法:
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
}
还可以有返回值:
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
};
引入JVM常量API
每个Java类文件都有一个常量池,该池存储该类中字节码指令的操作。广义上讲,常量池中的条目要么描述运行时artifacts(例如类和方法),要么描述简单值(例如字符串和整数)。
所有这些条目都称为可加载常量,因为它们可以用作ldc指令的参数(“加载常量”)。它们也可能出现在invokedynamic指令的引导方法的静态参数列表中。执行ldc或invokedynamic指令会导致将可加载常量解析为标准Java类型(如Class,String或int)的“实时”值。
处理类文件的程序需要对字节码指令进行建模,然后对可加载常量进行建模。但是,使用标准Java类型对可加载常量进行建模是不够的。
描述一个字符串(一个CONSTANT_String_info条目)的可加载常量可能是可以接受的,因为生成一个“live” String对象是很简单的,但是对于描述一个类(一个CONSTANT_Class_info条目)的一个可加载常量来说,这是有问题的,因为生成一个“live”类对象依赖于类加载的正确性和一致性。
在实际应用中,类加载具有许多环境依赖性和失败的情况,例如:所需的类不存在或请求者可能无法访问;类加载的结果随上下文而变化;加载类具有副作用;有时根本不可能加载类。
因此,处理可加载常量的程序如果能够操纵类和方法,并且以纯名义上的符号形式操纵诸如方法句柄和动态计算的常量之类的artifacts,则它们将变得更加简单。
具体来说就是java.base模块新增了java.lang.invoke.constant包(。包中定义了一系列基于值的符号引用(JVMS 5.1)类型,它们能够描述每种可加载常量。
前面都是编译相关改进,加粗的是和开发者相关的,这是关于 方法句柄的api,而我们的 lambda表达式就是通过匿名内部类,invokedynamic,方法句柄(MethodHandle)来实现的
64-bit Arm platform (arm64)
64-bit Arm platform (arm64),也可以称之为aarch64;之前JDK有两个关于aarch64的实现,分别是src/hotspot/cpu/arm以及open/src/hotspot/cpu/aarch64,它们的实现重复了,为了集中精力更好地实现aarch64,该特性在源码中删除了open/src/hotspot/cpu/arm中关于64-bit的实现,保留其中32-bit的实现,于是open/src/hotspot/cpu/aarch64部分就成了64-bit ARM architecture的默认实现
默认CDS档案
在64位平台上使用默认类列表增强JDK构建过程以生成类数据共享(CDS)归档。
java10的新特性JEP 310: Application Class-Data Sharing 扩展了JDK5引入的Class-Data Sharing,支持application的Class-Data Sharing;Class-Data Sharing可以用于多个JVM共享class,提升启动速度,最早只支持system classes及serial GC,JDK9对其进行扩展以支持application classes及其他GC算法,并在JDK10中开源出来(以前是commercial feature
);JDK11将-Xshare:off改为默认-Xshare:auto,以更加方便使用CDS特性;JDK12的这个特性即在64-bit平台上编译jdk的时候就默认在${JAVA_HOME}/lib/server目录下生成一份名为classes.jsa的默认archive文件(大概有18M
)方便大家使用
G1的可流动混合收集
G1在garbage collection的时候,一旦确定了collection set(CSet
)开始垃圾收集这个过程是without stopping的,当collection set过大的时候,此时的STW时间会过长超出目标pause time,这种情况在mixed collections时候比较明显。这个特性启动了一个机制,当选择了一个比较大的collection set,允许将其分为mandatory(强制)及optional(可选)两部分(在 G1 完成收集强制性部分后,如果还有剩余时间, G1 将开始以更精细的级别收集可选部分。此可选部分的收集粒度取决于所剩时间,最多一次归结为一个区域。在完成可选集合集的任何部分的收集后,G1 可以根据剩余时间决定停止收集。
)来将mixed collections从without stopping变为abortable,以更好满足指定pause time的目标;
从G1中立即返回未使用的已提交内存
增强 G1 垃圾收集器,以便在空闲时自动将 Java 堆内存返回到操作系统
目前,G1 垃圾收集器可能不会及时将承诺的 Java 堆存储器返回到操作系统。G1 仅在完整的 GC 或并发周期内从 Java 堆中返回内存。由于 G1 努力完全避免完整的 GC,并且仅触发基于 Java 堆占用和分配活动的并发周期,因此在许多情况下,除非被迫在外部这样做,否则它不会返回 Java 堆内存。
参考博客