JDK14的重大更新

一.JDK 14版本中的重大更改

1.1 Java SE 14和JDK 14中的一些更改

  • Switch进行了扩展,因此可以用作语句或表达式,以便两种形式都可以使用传统case ... :标签(带有直通)或新case ... -> 标签(不带有直通),还可以使用新的语句从中产生值开关表达式。

    示例:

    "->"以表示如果标签匹配则仅执行标签右边的代码。建议每种情况允许多个常量,以逗号分隔
    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);
    }
    
    
  • G1进行了增强,以提高非均匀内存访问(NUMA)存储系统上的分配性能

    G1的堆组织为固定大小区域的集合。一个区域通常是一组物理页面,尽管使用(通过-XX:+UseLargePages)大页面时,多个区域可能组成一个物理页面。

    如果+XX:+UseNUMA指定了该选项,则在初始化JVM时,区域将平均分布在可用NUMA节点的总数上。在开始时固定每个区域的NUMA节点有些不灵活,但是可以通过以下增强来缓解。为了为mutator线程分配新的对象,G1可能需要分配一个新的区域。它将通过从NUMA节点中优先选择一个与当前线程绑定的空闲区域来执行此操作,以便将对象保留在年轻代中的同一NUMA节点上。如果在为变量分配区域的过程中,同一NUMA节点上没有空闲区域,则G1将触发垃圾回收。要评估的另一种想法是,从距离最近的NUMA节点开始,按距离顺序在其他NUMA节点中搜索自由区域。

    我们不会尝试将对象保留在旧版本的同一NUMA节点上。

  • 现在,可以将JDK Flight Recorder数据作为数据流使用,以进行连续监视。

    描述

    该包装jdk.jfr.consumer,在模块jdk.jfr,与功能扩展到订阅事件异步。用户可以直接从磁盘存储库读取记录数据或从磁盘存储流中读取数据,而无需转储记录文件。与流进行交互的方式是注册一个处理程序,例如lambda函数,以响应事件的到来而被调用。

    以下示例显示了总体CPU使用率和竞争超过10毫秒的锁定。

    try (var rs = new RecordingStream()) {
      rs.enable("jdk.CPULoad").withPeriod(Duration.ofSeconds(1));
      rs.enable("jdk.JavaMonitorEnter").withThreshold(Duration.ofMillis(10));
      rs.onEvent("jdk.CPULoad", event -> {
        System.out.println(event.getFloat("machineTotal"));
      });
      rs.onEvent("jdk.JavaMonitorEnter", event -> {
        System.out.println(event.getClass("monitorClass"));
      });
      rs.start();
    }
    

    RecordingStream类实现了接口jdk.jfr.consumer.EventStream,该接口提供了一种统一的方式来过滤和使用事件,无论源是实时流还是磁盘上的文件。

  • 添加了新的特定于JDK的文件映射模式,因此该 FileChannelAPI可用于创建 MappedByteBuffer引用非易失性(NVM)内存的实例。

    建议的特定于JDK的API更改

    1. MapMode通过新模块中的公共API 公开新的枚举值

    一个新模块jdk.nio.mapmode将会导出一个同名的新软件包。一个公共扩展名枚举ExtendedMapMode将添加到此包中:

    package jdk.nio.mapmode;
    . . .
    public class ExtendedMapMode {
        private ExtendedMapMode() { }
    
        public static final MapMode READ_ONLY_SYNC = . . .
        public static final MapMode READ_WRITE_SYNC = . . .
    }
    

    调用FileChannel::map方法分别创建MappedByteBuffer在NVM设备文件上映射的只读或读写映射时,将使用新的枚举值。UnsupportedOperationException如果这些标志在不支持NVM设备文件映射的平台上传递,则将抛出An 。在受支持的平台上,仅当目标FileChannel实例是从通过NVM设备打开的文件派生时,才将这些新值作为参数传递。在任何其他情况下,IOException都将抛出。

    ​ 2.发布BufferPoolMXBean跟踪持久性MappedByteBuffer统计信息

    ManagementFactory类提供的方法List getPlatformMXBeans(Class)可用于检索的列表BufferPoolMXBean实例的跟踪counttotal_capacity以及memory_used用于映射或直接字节缓冲器的现有类别。它将进行修改以返回一个额外的新BufferPoolMXBean名称"mapped - 'non-volatile memory'",该名称将跟踪MappedByteBuffer当前使用模式ExtendedMapMode.READ_ONLY_SYNC或映射的所有实例的上述统计信息ExtendedMapMode.READ_WRITE_SYNC。现有的BufferPoolMXBean以名字mapped只会继续跟踪统计MappedByteBuffer情况目前正在与模式映射MapMode.READ_ONLYMapMode.READ_WRITEMapMode.PRIVATE

  • 允许使用特定于区域设置的记帐格式来设置货币格式,例如($ 3.27)而不是-$ 3.27。

    可以通过调用带有“ u-cf-account” Unicode语言环境扩展名的NumberFormat.getCurrencyInstanceInstance(Locale)获得具有记帐样式的货币格式实例,在某些语言环境中,该格式的金额用括号括起来。例如在Locale.US中,它将格式化为“($ 3.27)”,而不是“-$ 3.27”。

    更多详情https://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Currency_Formats

  • 进行了增强,com.sun.management.OperatingSystemMXBean 以确保其根据当前操作环境(例如容器环境)报告值。MXBean用于在操作系统上获取信息的工具已针对容器环境进行了改进。

    当Java在容器中运行时,许多OperatingSystemMXBean访问器方法将返回基于主机的信息,而不是特定于容器的数据。

    jdk / open / src / jdk.management / unix / classes / com / sun / management / internal / OperatingSystemImpl.java包含以下提取主机特定数据的本机方法。应该检查这些方法以确定是否有特定于容器的此信息源。

      private native long getCommittedVirtualMemorySize0();
      private native long getFreePhysicalMemorySize0();
      private native long getFreeSwapSpaceSize0();
      private native long getMaxFileDescriptorCount0();
      private native long getOpenFileDescriptorCount0();
      private native long getProcessCpuTime0();
      private native double getProcessCpuLoad0();
      private native double getSystemCpuLoad0();
      private native long getTotalPhysicalMemorySize0();
      private native long getTotalSwapSpaceSize0();
    

    这些Java方法应该首先尝试从内部容器Metrics API中提取此信息(如果有)。否则,它应该调用这些现有的本机方法。

    以下是容器度量标准的实现类:

    jdk/open/src/java.base/ share/classes/jdk/internal/platform/Container.java
    jdk/open/src/java.base/share/classes/jdk/internal/platform /Metrics.java
    

1.2 实验,预览和孵化器功能

  • Records是 Java语言的预览功能,它提供了一种紧凑的语法来声明类,这些类是浅层不可变数据的透明持有者。

    记录是Java语言中一种新型的类型声明。像an一样enum,a record是类的受限形式。它声明其表示形式,并提交与该表示形式匹配的API。记录放弃了类通常享有的自由:将API与表示分离的能力。作为回报,记录获得了很大程度的简洁性。

    记录具有名称和状态描述。状态描述声明记录的组成部分。(可选)记录具有正文。例如:

    record Point(int x, int y) { }
    

    因为记录在语义上声称是其数据的简单,透明持有者,所以记录会自动获取许多标准成员:

    • 状态描述每个组成部分的私有最终字段;
    • 状态描述的每个组件的公共读取访问器方法,其名称和类型与该组件相同;
    • 一个公共构造函数,其签名与状态描述相同,该构造函数根据相应的参数初始化每个字段;
    • 的实现equalshashCode该说两条记录是相等的,如果它们是相同类型的并且包含相同的状态; 和
    • 该实现toString包括所有记录组件的字符串表示形式及其名称。

    换句话说,记录的表示是从状态描述中机械地,完全地从状态描述中得出的,构造,解构(最初是访问器,当我们具有模式匹配时是解构模式),相等性和显示的协议也是如此。

  • 模式匹配instanceof是一种Java语言预览功能,可简化 instanceof-and-cast习惯用法。

    //原来的版本
    if (obj instanceof String) {
        String s = (String) obj;
        // use s
    }
    //新版本
    if (obj instanceof String s || s.length() > 5) {.. s.contains(..) ..}
    
  • 文本块是多行字符串文字,它避免了大多数转义序列的需要,以可预测的方式自动设置字符串的格式,并在需要时使开发人员可以控制格式。文本块在JDK 13中作为预览功能引入。通过添加两个新的转义序列,可以在JDK 14中再次预览文本块。

  • jpackage,这是用于打包自包含Java应用程序的简单工具。

  • 引入了一种API,该API允许Java程序有效访问Java堆之外的外部内存。

  • Z垃圾收集器(ZGC)以前仅适用于Linux,是Windows和macOS上的一项实验性功能

    Windows实现的ZGC需要进行以下工作:

    • *支持多映射内存。*ZGC使用彩色指针需要支持堆多重映射,以便可以从进程地址空间中的多个不同位置访问同一物理内存。在Windows上,分页文件支持的内存为物理内存提供了一个标识(句柄),该标识与映射它的虚拟地址无关。使用此标识,ZGC可以将同一物理内存映射到多个位置。

    • *支持将分页文件支持的内存映射到保留的地址空间。*Windows内存管理API不如POSIX的mmap / munmap灵活,尤其是在将文件支持的内存映射到以前保留的地址空间区域中时。为此,ZGC将使用Windows概念的地址空间占位符。Windows 10和Windows Server版本1803中引入了占位符概念。不会实现对Windows较早版本的ZGC支持。

    • *支持映射和取消映射堆的任意部分。*ZGC的堆布局与其动态调整堆页面大小(以及重新调整大小)相结合,需要支持映射和取消映射任意堆粒子。此要求与Windows地址空间占位符结合使用时,需要特别注意,因为占位符必须由程序显式拆分/合并,而不是由操作系统自动拆分/合并(如在Linux上)。

    • *支持提交和取消提交堆的任意部分。*ZGC可以在Java程序运行时动态地提交和取消提交物理内存。为了支持这些操作,物理内存将被划分为多个分页文件段并由其支持。每个分页文件段都对应一个ZGC堆粒度,并且可以独立于其他段进行提交和取消提交。

    ZGC的macOS实现由两部分组成:

    • 支持macOS上的多映射内存。ZGC设计大量使用彩色指针,因此在macOS上我们需要一种将多个虚拟地址(在算法中包含不同颜色)映射到同一物理内存的方法。我们将为此使用mach microkernel mach_vm_remap API。堆的物理内存在单独的地址视图中维护,从概念上讲类似于文件描述符,但位于(主要是)连续的虚拟地址中。该内存重新映射到内存的各种ZGC视图中,代表了算法的不同指针颜色。
    • ZGC支持不连续的内存保留。在Linux上,我们在初始化期间保留16TB的虚拟地址空间。为此,我们假设没有共享库将映射到所需的地址空间。在默认的Linux配置上,这是一个安全的假设。但是,在macOS上,ASLR机制会侵入我们的地址空间,因此ZGC必须允许堆保留不连续。假设VM实现使用单个连续的内存预留,则共享的VM代码也必须停止。其结果是,GC API,如is_in_reserved()reserved_region()base()将被删除CollectedHeap

二.删除的API,工具和组件

2.1 Java SE 14中删除的API

Packages

java.security.acl      

Interfaces

java.security.acl.Acl
java.security.acl.AclEntry
java.security.acl.Group
java.security.acl.Owner
java.security.acl.Permission
java.util.jar.Pack200.Packer    
java.util.jar.Pack200.Unpacker            

Classes

java.util.jar.Pack200   

2.2JDK 14中删除的功能和组件

1.删除并发标记扫描(CMS)垃圾收集器

CMS垃圾收集器已被删除。

2.删除Pack200工具和API

Pack200工具和API在JDK 11中已弃用,在JDK 14中已删除。

pack200unpack200工具,并 Pack200java.util.jar.Pack200包已被删除。
本文的分享暂时就到这里,希望对您有所帮助
关注 Java有货领取更多资料

联系小编。微信:372787553,带您进群互相学习
左侧小编微信,右侧获取免费资料
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_38937840/article/details/105054595