转载

JDK12新特性详解 原 荐

JDK8新特性详解

JDK9新特性详解

JDK10新特性详解

JDK11新特性详解

简介:JDK12于2019-03-19正式发布。

1、JDK12之Shenandoah低暂停时间垃圾收集器(实验性)

定义:

    添加一个名为Shenandoah的新垃圾收集(GC)算法,通过与正在运行的Java线程同时进行疏散工作来减少GC暂停时间。使用Shenandoah的暂停时间与堆大小无关,
这意味着无论堆是200MB还是200GB,您都将具有相同的一致暂停时间。

非目标:

    这不是一个统治所有人的GC。还有其他垃圾收集算法可以优先考虑吞吐量或内存占用而不是响应性。Shenandoah是适用于评估响应性和可预测的短暂停顿
的应用程序的算法。目标不是解决所有JVM暂停问题。由于GC之外的其他原因(例如安全时间点(TTSP)发布或监控通胀)而暂停时间超出了此JEP的范围。

构建和调用:

作为实验性功能,Shenandoah将-XX:+UnlockExperimentalVMOptions在命令行中要求。Shenandoah构建系统会自动禁用不受支持的配置。下游建设者可以选择--with-jvm-features=-shenandoahgc在其他支持的平台上禁用构建Shenandoah。
要启用/使用Shenandoah GC,需要以下JVM选项:-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC

2、JDK12之Microbenchmark Suite

定义:

    在JDK源代码中添加一套基本的微基准测试,使开发人员可以轻松运行现有的微基准测试并创建新的基准测试。

目标:

1、基于[Java Microbenchmark线束(JMH)] [1]
2、稳定且经过调整的基准测试,针对持续性能测试
    2.1、在功能发布的功能完成里程碑之后,以及非功能版本之后的稳定且不移动的套件
    2.2、支持与先前JDK版本的适用测试比较
3、简单
    3.1 轻松添加新基准
    3.2 在API和选项更改,不推荐使用或在开发期间删除时,可以轻松更新测试
    3.3 易于构建
    3.4 易于查找和运行基准
    3.5 支持JMH更新
    3.6 在套件中包含大约一百个基准的初始集

3、JDK12之Switch表达式

许多break使它不必要地冗长,并且这种视觉噪声经常掩盖难以调试的错误,其中缺失break语句意味着发生意外的掉落。

JDK12之前的版本:

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;
}

JDK12:我们建议引入一种新形式的开关标签,写成“case L ->”表示如果标签匹配,则只执行标签右侧的代码。

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);
}

许多Switch基本上是Switch表达式的模拟,其中每个臂都分配给一个公共目标变量或返回一个值:

JDK12之前:

int numLetters;
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        numLetters = 6;
        break;
    case TUESDAY:
        numLetters = 7;
        break;
    case THURSDAY:
    case SATURDAY:
        numLetters = 8;
        break;
    case WEDNESDAY:
        numLetters = 9;
        break;
    default:
        throw new IllegalStateException("Wat: " + day);
}

JDK12:将此表达为一种陈述是迂回的,重复的,并且容易出错。作者意味着我们应该计算numLetters每一天的价值。应该可以直接说,使用更清晰,更安全Switch表达式

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};

如果将它用在方法上,则可以为:

static void howMany(int k) {
    switch (k) {
        case 1 -> System.out.println("one");
        case 2 -> System.out.println("two");
        case 3 -> System.out.println("many");
    }
}

或者类上,我想到的这个switch这个功能可以用在抽象工厂类方面。

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

4、JDK12之JVM常量API

摘要:

引入API来模拟关键类文件和运行时工件的名义描述,特别是可从常量池加载的常量。

动机:

    每个Java类文件都有一个常量池,用于存储类中字节码指令的操作数。从广义上讲,常量池中的条目描述了运行时工件(如类和方法)或简单值(如字符串和整数)。
所有这些条目都称为可加载常量,因为它们可以作为ldc指令的操作数(“加载常量”)。它们也可能出现在invokedynamic指令的bootstrap方法的静态参数列表中。
执行一个ldc或invokedynamic指令导致加载常数被解析成一个标准的Java类,如“活”的值Class,String或int。
    操作class文件的程序需要对字节码指令进行建模,并依次对可加载的常量进行建模。但是,使用标准Java类型来模拟可加载常量是不合适的。
描述字符串(CONSTANT_String_info条目)的可加载常量可能是可以接受的,因为生成“实时” String对象很简单,
但是对于描述类(CONSTANT_Class_info条目)的可加载常量是有问题的,因为产生“实时”Class object依赖于类加载的正确性和一致性。
不幸的是,类加载有许多环境依赖和失败模式:所需的类不存在或者请求者可能无法访问; 类加载的结果因上下文而异; 装载类有副作用;
有时类加载可能根本不可能(例如当所描述的类尚不存在或者无法加载时,如在编译那些相同类或在jlink转换期间)。
    因此,处理可加载常量的程序如果能够以纯粹的名义符号形式操作类和方法,以及不太知名的工件(如方法句柄和动态计算常量),则会更简单:
    1、字节码解析和生成库必须以符号形式描述类和方法句柄。如果没有标准机制,它们必须采用ad-hoc机制,无论是ASM的描述符类型Handle,还是字符串元组(方法所有者,方法名称,方法描述符),或者这些机制的特殊(并且容易出错)编码单个字符串。
    2、如果它们可以在符号域中工作而不是使用“实时”类和方法句柄,invokedynamic那么通过旋转字节码(例如LambdaMetafactory)来操作的Bootstraps 将更简单。
    3、编译器和脱机转换器(例如jlink插件)需要描述无法加载到正在运行的VM的类的类和成员。编译器插件(例如注释处理器)同样需要用符号术语来描述程序元素。

5、JDK12之一个AArch64端口,而不是两个

摘要:

arm64在保留32位ARM端口和64位aarch64端口的同时,删除与端口相关的所有源。

动机:

删除此端口将允许所有贡献者将他们的精力集中在单个64位ARM实现上,并消除维护两个端口所需的重复工作。

6、JDK12之默认CDS档案

摘要:

在64位平台上使用默认类列表增强JDK构建过程以生成类数据共享(CDS)归档。

目标:

1、改善开箱即用的启动时间
2、消除用户运行-Xshare:dump以从CDS中受益的需要

7、JDK12之G1的可流动混合收集

摘要:

如果G1混合集合可能超过暂停目标,则使其可以中止。

动机:

    G1的目标之一是满足用户提供的暂停时间目标以暂停其收集暂停。G1使用高级分析引擎来选择在集合期间要完成的工作量(这部分基于应用程序行为)。
此选择的结果是一组称为<em>集合集</em>的区域。一旦确定了集合集并且已经开始集合,则G1必须在不停止的情况下收集集合集的所有区域中的所有活动对象。如果启
发式选择过大的收集集,则此行为可导致G1超过暂停时间目标,例如,如果应用程序的行为发生变化,以致启发式工作在“陈旧”数据上,则可能发生这种情况。
特别是在混合集合期间可以观察到这种情况,其中集合集通常可以包含太多旧区域。需要一种机制来检测启发式方法何时反复为集合选择错误的工作量,如果是,
则让G1逐步递增地执行收集工作,其中集合可以在每个步骤之后中止。这种机制将允许G1更频繁地满足暂停时间目标。

8、JDK12之从G1中立即返回未使用的已提交内存

摘要:

增强G1垃圾收集器,以便在空闲时自动将Java堆内存返回给操作系统。

成功指标:

如果应用程序活动非常低,G1应该在合理的时间段内释放未使用的Java堆内存。

动机:

    目前G1垃圾收集器可能无法及时将已提交的Java堆内存返回给操作系统。G1仅在完整GC或并发周期内从Java堆返回内存。由于G1很难完全
避免完整的GC,并且只触发基于Java堆占用和分配活动的并发周期,因此在许多情况下它不会返回Java堆内存,除非在外部强制执行此操作。
    在使用资源支付的容器环境中,这种行为特别不利。即使在VM由于不活动而仅使用其分配的内存资源的一小部分的阶段,G1也将保留所有Java
堆。这导致客户始终为所有资源付费,云提供商无法充分利用其硬件。
    如果VM能够检测到Java堆的利用率不足(“空闲”阶段),并在此期间自动减少其堆使用量,则两者都将受益。
    Shenandoah和OpenJ9的GenCon收集器已经提供了类似的功能。
原文  https://my.oschina.net/mdxlcj/blog/3102739
正文到此结束
Loading...