2019年9月17 发布 Java 13

2017年8月,JCP执行委员会提出将Java的发布频率改为每六个月一次,新的发布周期严格遵循时间点,将在每年的3月份和9月份发布。

目前,JDK官网上已经可以看到JDK 13的进展,最新版的JDK 13将于2019年9月17日发布。

目前,JDK13处于Release-Candidate Phase(发布候选阶段),将于9月17日正式发布。目前该版本包含的特性已经全部固定,主要包含以下五个:

JEP 350,Dynamic CDS Archives

JEP 351,ZGC: Uncommit Unused Memory

JEP 353,Reimplement the Legacy Socket API

JEP 354: Switch Expressions (Preview)

JEP 355,Text Blocks (Preview)

下面来逐一介绍下这五个重要的特性。

Dynamic CDS Archives

这一特性是在JEP310:Application Class-Data Sharing基础上扩展而来的,Dynamic CDS Archives中的CDS指的就是Class-Data Sharing。

那么,这个JEP310是个啥东西呢?

我们知道在同一个物理机/虚拟机上启动多个JVM时,如果每个虚拟机都单独装载自己需要的所有类,启动成本和内存占用是比较高的。所以Java团队引入了CDS的概念,通过把一些核心类在每个JVM间共享,每个JVM只需要装载自己的应用类,启动时间减少了,另外核心类是共享的,所以JVM的内存占用也减少了。

CDS 只能作用于 Boot Class Loader 加载的类,不能作用于 App Class Loader 或者自定义的 Class Loader 加载的类。

在 Java 10 中,则将 CDS 扩展为 AppCDS,顾名思义,AppCDS 不止能够作用于 Boot Class Loader了,App Class Loader 和自定义的 Class Loader 也都能够起作用,大大加大了 CDS 的适用范围。也就说开发自定义的类也可以装载给多个JVM共享了。

Java 10中包含的JEP310的通过跨不同Java进程共享公共类元数据来减少了内存占用和改进了启动时间。

但是,JEP310中,使用AppCDS的过程还是比较复杂的,需要有三个步骤:

1、决定要 Dump 哪些 Class
2、将类的内存 Dump 到归档文件中
3、使用 Dump 出来的归档文件加快应用启动速度

这一次的JDK 13中的JEP 350 ,在JEP310的基础上,又做了一些扩展。允许在Java应用程序执行结束时动态归档类,归档类将包括默认的基础层 CDS(class data-sharing)存档中不存在的所有已加载的应用程序类和库类。

也就是说,在Java 13中再使用AppCDS的时候,就不在需要这么复杂了。

ZGC: Uncommit Unused Memory

在讨论这个问题之前,想先问一个问题,JVM的GC释放的内存会还给操作系统吗?

GC后的内存如何处置,其实是取决于不同的垃圾回收器的。因为把内存还给OS,意味着要调整JVM的堆大小,这个过程是比较耗费资源的。

在JDK 11中,Java引入了ZGC,这是一款可伸缩的低延迟垃圾收集器,但是当时只是实验性的。并且,ZGC释放的内存是不会还给操作系统的。

而在Java 13中,JEP 351再次对ZGC做了增强,本次 ZGC 可以将未使用的堆内存返回给操作系统。之所以引入这个特性,是因为如今有很多场景中内存是比较昂贵的资源,在以下情况中,将内存还给操作系统还是很有必要的:

  • 1、那些需要根据使用量付费的容器
  • 2、应用程序可能长时间处于空闲状态并与许多其他应用程序共享或竞争资源的环境。
  • 3、应用程序在执行期间可能有非常不同的堆空间需求。例如,启动期间所需的堆可能大于稍后在稳定状态执行期间所需的堆。

Reimplement the Legacy Socket API

使用易于维护和调试的更简单、更现代的实现替换 java.net.Socket 和 java.net.ServerSocket API。

java.net.Socket和java.net.ServerSocket的实现非常古老,这个JEP为它们引入了一个现代的实现。现代实现是Java 13中的默认实现,但是旧的实现还没有删除,可以通过设置系统属性jdk.net.usePlainSocketImpl来使用它们。

运行一个实例化Socket和ServerSocket的类将显示这个调试输出。这是默认的(新的):

java -XX:+TraceClassLoading JEP353  | grep Socket
[0.033s][info   ][class,load] java.net.Socket source: jrt:/java.base
[0.035s][info   ][class,load] java.net.SocketOptions source: jrt:/java.base
[0.035s][info   ][class,load] java.net.SocketImpl source: jrt:/java.base
[0.039s][info   ][class,load] java.net.SocketImpl$$Lambda$1/0x0000000800b50840 source: java.net.SocketImpl
[0.042s][info   ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base
[0.042s][info   ][class,load] sun.nio.ch.NioSocketImpl source: jrt:/java.base
[0.043s][info   ][class,load] sun.nio.ch.SocketDispatcher source: jrt:/java.base
[0.044s][info   ][class,load] java.net.DelegatingSocketImpl source: jrt:/java.base
[0.044s][info   ][class,load] java.net.SocksSocketImpl source: jrt:/java.base
[0.044s][info   ][class,load] java.net.ServerSocket source: jrt:/java.base
[0.045s][info   ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:/java.base
[0.045s][info   ][class,load] java.net.ServerSocket$1 source: jrt:/java.base

上面输出的sun.nio.ch.NioSocketImpl就是新提供的实现。

如果使用旧的实现也是可以的(指定参数jdk.net.usePlainSocketImpl):

$ java -Djdk.net.usePlainSocketImpl -XX:+TraceClassLoading JEP353  | grep Socket
[0.037s][info   ][class,load] java.net.Socket source: jrt:/java.base
[0.039s][info   ][class,load] java.net.SocketOptions source: jrt:/java.base
[0.039s][info   ][class,load] java.net.SocketImpl source: jrt:/java.base
[0.043s][info   ][class,load] java.net.SocketImpl$$Lambda$1/0x0000000800b50840 source: java.net.SocketImpl
[0.046s][info   ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base
[0.047s][info   ][class,load] java.net.AbstractPlainSocketImpl source: jrt:/java.base
[0.047s][info   ][class,load] java.net.PlainSocketImpl source: jrt:/java.base
[0.047s][info   ][class,load] java.net.AbstractPlainSocketImpl$1 source: jrt:/java.base
[0.047s][info   ][class,load] sun.net.ext.ExtendedSocketOptions source: jrt:/java.base
[0.047s][info   ][class,load] jdk.net.ExtendedSocketOptions source: jrt:/jdk.net
[0.047s][info   ][class,load] java.net.SocketOption source: jrt:/java.base
[0.047s][info   ][class,load] jdk.net.ExtendedSocketOptions$ExtSocketOption source: jrt:/jdk.net
[0.047s][info   ][class,load] jdk.net.SocketFlow source: jrt:/jdk.net
[0.047s][info   ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions source: jrt:/jdk.net
[0.047s][info   ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions$1 source: jrt:/jdk.net
[0.048s][info   ][class,load] jdk.net.LinuxSocketOptions source: jrt:/jdk.net
[0.048s][info   ][class,load] jdk.net.LinuxSocketOptions$$Lambda$2/0x0000000800b51040 source: jdk.net.LinuxSocketOptions
[0.049s][info   ][class,load] jdk.net.ExtendedSocketOptions$1 source: jrt:/jdk.net
[0.049s][info   ][class,load] java.net.StandardSocketOptions source: jrt:/java.base
[0.049s][info   ][class,load] java.net.StandardSocketOptions$StdSocketOption source: jrt:/java.base
[0.051s][info   ][class,load] sun.net.ext.ExtendedSocketOptions$$Lambda$3/0x0000000800b51440 source: sun.net.ext.ExtendedSocketOptions
[0.057s][info   ][class,load] java.net.DelegatingSocketImpl source: jrt:/java.base
[0.057s][info   ][class,load] java.net.SocksSocketImpl source: jrt:/java.base
[0.058s][info   ][class,load] java.net.ServerSocket source: jrt:/java.base
[0.058s][info   ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:/java.base
[0.058s][info   ][class,load] java.net.ServerSocket$1 source: jrt:/java.base

上面的结果中,旧的实现java.net.PlainSocketImpl被用到了。

Switch Expressions (Preview)

在JDK 12中引入了Switch表达式作为预览特性。JEP 354修改了这个特性,它引入了yield语句,用于返回值。这意味着,switch表达式(返回值)应该使用yield, switch语句(不返回值)应该使用break。

在以前,我们想要在switch中返回内容,还是比较麻烦的,一般语法如下:

int i;
switch (x) {
    case "1":
        i=1;
        break;
    case "2":
        i=2;
        break;
    default:
        i = x.length();
        break;
}

在JDK13中使用以下语法:

int i = switch (x) {
    case "1" -> 1;
    case "2" -> 2;
    default -> {
        int len = args[1].length();
        yield len;
    }
};

或者

int i = switch (x) {
    case "1": yield 1;
    case "2": yield 2;
    default: {
        int len = args[1].length();
        yield len;
    }
};

在这之后,switch中就多了一个关键字用于跳出switch块了,那就是yield,他用于返回一个值。和return的区别在于:return会直接跳出当前循环或者方法,而yield只会跳出当前switch块。

Text Blocks (Preview)

在JDK 12中引入了Raw String Literals特性,但在发布之前就放弃了。这个JEP在引入多行字符串文字(text block)在意义上是类似的。

text block,文本块,是一个多行字符串文字,它避免了对大多数转义序列的需要,以可预测的方式自动格式化字符串,并在需要时让开发人员控制格式。

我们以前从外部copy一段文本串到Java中,会被自动转义,如有一段以下字符串:

 <html>
  <body>
      <p>Hello, world</p>
  </body>
</html>

将其复制到Java的字符串中,会展示成以下内容:

"<html>\n" +
"    <body>\n" +
"        <p>Hello, world</p>\n" +
"    </body>\n" +
"</html>\n";

即被自动进行了转义,这样的字符串看起来不是很直观,在JDK 13中,就可以使用以下语法了:

"""
<html>
  <body>
      <p>Hello, world</p>
  </body>
</html>
""";

使用“”“作为文本块的开始符合结束符,在其中就可以放置多行的字符串,不需要进行任何转义。看起来就十分清爽了。

如常见的SQL语句:

String query = """
    SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
    WHERE `CITY` = ‘INDIANAPOLIS‘
    ORDER BY `EMP_ID`, `LAST_NAME`;
""";

看起来就比较直观,清爽了。

总结

以上,就是JDK13中包含的5个特性,能够改变开发者的编码风格的主要有Text Blocks和Switch Expressions两个新特性,但是这两个特性还处于预览阶段。

而且,JDK13并不是LTS(长期支持)版本,如果你正在使用Java 8(LTS)或者Java 11(LTS),暂时可以不必升级到Java 13.

参考资料: https://openjdk.java.net/projects/jdk/13/ https://metebalci.com/blog/what-is-new-in-java-13/ https://www.jianshu.com/p/890196bf529a

原文地址:https://www.cnblogs.com/xichji/p/11533524.html

时间: 2024-08-29 09:16:42

2019年9月17 发布 Java 13的相关文章

【2019年4月17日】指数基金估值表(今日定投)

大家好,我是牛九老师,财经达人,专注于研究指数基金. 今天周四,我们定投的时间到了,推荐大家在支付宝中进行基金的购买,即方便又安全. 本周老师推荐的定投组合如下(下午三点之前在支付宝“基金栏目”搜索场外基金号码进行买入即可): 每只指数基金都是一只“会下金蛋的鹅”,我们要做的就是慢慢的喂养它,持之以恒它就会给我们带来稳定的回报. 我们以后采取的定投策略是:每周定投低估值的指数基金,定期不定额. 就是基金的估值越低,定投金额会略微增加,这样可以极大的摊低成本.(根据低估程度,采取1-2倍的定投基数

第三章 管道符、重定向与环境变量 2019年7月17日星期三 第四课

2019年7月17日星期三   第四课 2.7 文件目录管理命令 1.touch命令    创建空白文件或设置文件时间 如:touch haha.txt touch -d “19:00”   修改文件访问和者修改时间 -a 修改读取时间   -m 修改修改时间 -d前两个都修改 2.mkdir命令    创建目录 如果要创建迭代关系的目录要加参数  -p 如:mkdir -p a/b/c/d/e/f/g 3.cp命令    复制文件或目录 复制目录时要加参数 -r 如:cp -r Music/

4星|《环球科学》2019年01月号:只有13%的海洋仍然是荒野

<环球科学>2019年01月号 有趣可信的科普杂志.本期我感兴趣的话题:1:无血缘关系的夫妻间寿命的相关性,反而比与兄弟姐妹和父母的更紧密:2:海绵城市技术已经帮助费城等地减少了污染:3:社会越不平等,生活质量越差:4:环境恶化的根本原因是不平等,而不是人均收入:5:只有13%的海洋仍然是荒野. 总体评价4星,非常好. 以下是书中一些内容的摘抄,#号后面是kindle电子版中的页码: 1:近日,这群研究人员再次提出能够匹配更多指纹的“深度万能钥匙”,在1%的错误匹配率下,能够伪造出77%的指纹

【邀请函】9月17日第13期Spark公益大讲堂:Tachyon内核解析及Spark与Tachyon操作实战

Tachyon是大数据时代杀手锏级别的技术,是大数据时代必须掌握的技术. 通过Tachyon,分布式机器可以基于Tachyon构建的分布式内存文件存储系统来共享数据,这对分布式系统的机器协作和数据共享以及速度的提升都具有非凡的意义: 本次课程我们首先从Tachyon的架构入手,Tachyon的架构和启动原理,然后细致解析Tachyon的操作API,最后通过源码深入解析Spark下的Tachyon. Topic 1:Tachyon架构剖析 Tachyon架构解析: Tachyon安装.启动解析:

实验报告(2019年4月17日)

c程序实验报告 姓名:黄志乾????实验地点:教学楼514教室????实验时间:4月17日 实验项目: ???1.用for语句实现循环 ???2.用while循环语句实现循环 ???3.用do-while语句实现循环 ???4.用while语句和for语句配合实现循环 ???5.用for语句嵌套实现循环 一.实验目的与要求 1.用for语句实现循环 ● 掌握c语言逻辑运算和关系运算的规则 ● 掌握for语句实现循环的方法 ● 循环嵌套的使用 2.用while循环语句实现循环 ● 掌握while语

2019年12月20日 java学习知识记录

一个"java"源文件中是否可以有多个类? 有什么限制? 一个java的源文件中都可以都多个类 ,但是public的类只能有一个  而且public的名字要和文件名一致(大小写也得一致) java 有没有 goto? java中有goto 但是现在java中不使用 &和&&有什么区别? &和&&都是逻辑运算符 运算符两边的表达式,如果运算结果都是true的话,结果返回就为true   如果有一边的运算结果为false,那么结果返回的就为f

2019年5月17日-linux就该这么学-第7课

第5章 用户身份与文件权限 5.3 文件的特殊权限5.3.1 SUID:授予到二进制命令上的,用于获取的是文件所有者权限:执行临时的.有条件的特殊授权方法.5.3.2 SGID:(1) 让执行者临时拥有组的权限:(2) 在某个目录中创建的文件自动继承该目录的用户组.执行passwd命令时,就是在执行SUID权限.设置文件或目录的权限:chmod [参数] 权限 文件或目录名称:5.3.3 SBIT:保住位---可确保用户只能删除自己的文件,而不能删除其他用户的文件.5.4 文件的隐藏属性(1)

2019年10月17号 王腾飞 spss

开放数据库连接是为了解决异构数据库间的数据共享而产生的,现已成为WOSA的主要部分和基于Windows环境的一种数据库访问接口标准ODBC为异构数据库访问提供一个接口,允许应用程序以SQL为数据库取标准,存取不同DBMS管理的数据:使应用程序直接操纵DB中的数据,免除随DB改变而改变.用ODBC可以访问各类计算机上的DB中的文件,甚至访问如Excel表和 ASCII数据文件这类非数据库对象. 数据库变量命名只能用英文,英文首字母大写(如果你不会英语的话用汉语的拼音全拼或简拼首字母大写) 数据的编

计算机英语总结2019年11月3日 23:13:03

(1)DOS was the first widely-installed operating system on personal computers. (2)To command to check a diskette for flaws and creates a directory where all the names ofthe diskette's files will be stored. It is Ping command (3)While there are several