JDK11新特性

Oracle官方于2018年9月26日宣布Java11正式发布。目前Oracle 官方也已经宣布Java11正式可以商用,这是Java 大版本周期变化后的第一个长期支持版本,非常值得关注。最新发布的Java11一共包含17个JEP(JDK Enhancement Proposals,JDK 增强提案)。对于企业来说,选择Java11将意味着长期的、可靠的、可预测的技术路线图。...
摘要由CSDN通过智能技术生成

Oracle官方于2018年9月26日宣布Java11正式发布。目前Oracle 官方也已经宣布Java11正式可以商用,这是Java 大版本周期变化后的第一个长期支持版本,非常值得关注。最新发布的Java11一共包含17个JEP(JDK Enhancement Proposals,JDK 增强提案)。对于企业来说,选择Java11将意味着长期的、可靠的、可预测的技术路线图。其中免费的OpenJDK11确定将得到OpenJDK社区的长期支持,LTS版本将是可以放心选择的版本。由于JDK9和JDK10都是一个过渡版本,JDK11的特性是在JDK9中就有的,我在博客里也做了总结《 JDK9新特性(一)》《JDK9新特性(二)》 ,其中已经介绍过的新特性将不会在这篇文章出现。

从JVM GC的角度,JDK11引入了两种新的GC,其中包括也许是划时代意义的ZGC,虽然其目前还是实验特性,但是从能力上来看,这是JDK的一个巨大突破,为特定生产环境的苛刻需求提供了一个可能的选择。例如,对部分企业核心存储等产品,如果能够保证不超过10ms的GC暂停,可靠性会上一个大的台阶,这是过去我们进行GC调优几乎做不到的,是能与不能的问题。
对于G1 GC,相比于JDK8,升级到JDK11即可免费享受到:并行的Full GC,快速的CardTable扫描,自适应的堆占用比例调整(IHOP),在并发标记阶段的类型卸载等等。这些都是针对G1的不断增强,其中串行Full GC等甚至是曾经被广泛诟病的短板,你会发现GC配置和调优在JDK11中越来越方便。
云计算时代的监控、诊断和Profiling能力,这个是相比ZGC更具生产实践意义的特性。
Java的应用场景跨度很大,从单机长时间运行的Java应用,发展成为分布式、大的单体应用或小的Function、瞬时或长时间运行等,应用场景非常复杂。

JDK11为我们提供了更加强大的基础能力,主要是两部分

第一部分:JEP 328: Flight Recorder(JFR)是Oracle刚刚开源的强大特性。JFR是一套集成进入JDK、JVM内部的事件机制框架,通过良好架构和设计的框架,硬件层面的极致优化,生产环境的广泛验证,它可以做到极致的可靠和低开销。在SPECjbb2015等基准测试中,JFR的性能开销最大不超过1%,所以,工程师可以基本没有心理负担地在大规模分布式的生产系统使用,这意味着,我们既可以随时主动开启JFR进行特定诊断,也可以让系统长期运行JFR,用以在复杂环境中进行After-the-fact分析。
在保证低开销的基础上,JFR提供的能力可以应用在对锁竞争、阻塞、延迟,JVM GC、SafePoint等领域,进行非常细粒度分析。甚至深入JIT Compiler内部,全面把握热点方法、内联、逆优化等等。JFR提供了标准的Java、C++等扩展API,可以与各种层面的应用进行定制、集成,为复杂的企业应用栈或者复杂的分布式应用,提供All-in-One解决方案。
Flight Recorder相当于飞机的黑匣子,不会影响JVM的运行(最大性能开销不超过1%),而且是不断记录JVM的运行监控参数,而这一切都是内建在JDK和JVM内部的,并不需要额外的依赖,开箱即用。
第二部分:JEP 331: Low-Overhead Heap Profiling。它来源于Google等业界前沿厂商的一线实践,通过获取对象分配细节,为JDK补足了对象分配诊断方面的一些短板,工程师可以通过JVMTI使用这个能力增强自身的工具。

从 Java 类库发展的角度来看,JDK 11 最大的进步也是两个方面

第一部分:HTTP/2 Client API,新的HTTP API提供了对HTTP/2等业界前沿标准的支持,精简而又友好的API接口,与主流开源API(如Apache HttpClient, Jetty, OkHttp 等)对等甚至更高的性能。与此同时它是JDK在Reactive-Stream方面的第一个生产实践,广泛使用了Java Flow API等,终于让Java标准HTTP类库在扩展能力等方面,满足了现代互联网的需求。
第二部分:安全类库、标准等方面的大范围升级,其中特别是 JEP 332: Transport Layer Security (TLS) 1.3,除了在安全领域的重要价值,它还是中国安全专家范学雷所领导的JDK项目,完全不同于以往的修修补补,是个非常大规模的工程。
除此之外,JDK 还在逐渐进行瘦身工作,或者偿还 JVM、Java 规范等历史欠账,例如:Deprecate the Nashorn JavaScript Engine,它进一步明确了 Graal 很有可能将成为 JVM 向前演进的核心选择,Java-on-Java 正在一步步的成为现实。

Dynamic Class-File Constants

Java的类型文件格式将被拓展,支持一种新的常量池格式:CONSTANT_Dynamic,加载CONSTANT_Dynamic会将创建委托给bootstrap方法。其目标是降低开发新形式的可实现类文件约束带来的成本和干扰。
上面的说法可能难以理解,我将换一个方式来说明这个新特性。在JDK1.5之前,Java程序中的常量值只能是字符串或原始类型。这些常量作为文字内置在语言中,甚至由javac编译器假定以减小类文件的大小。

class ConstantSample {
    
final String field = "foo";
void hello() {
System.out.print(field);
}
}

为了表示这样的常量值,任何Java类文件都包含了一个常量池,这意味着在方法中使用或用作字段值的常量,但也包含描述类的其他不可变信息,例如类的名称或被调用方法的名称及其声明的类型名称等信息。一旦在类的常量池中记录了一个值,就可以通过指向常量池中特定条目的偏移量来引用该值。这样做,在整个类中重复的值仅需要存储一次,因为偏移量可以多次引用。 JVM甚至可以通过遍历在常量池中找到的字符串来跨类对常量字符串进行重复数据删除。
接下来我要说的是常量池存储的局限性,类文件的常量池中值的这种表示形式非常适合简单的值,例如字符串和数字等基本常量。但是同时,当javac没有发现常量时,它可能会带来非常直观的后果:

class NoConstantSample {
    
final String field = "foo".toString();
void hello() {
System.out.print(field);
}
}

尽管toString方法对于字符串来说是微不足道的,但是这种情况对于不评估Java方法的javac仍然未知。因此,编译器不能再发出常量池的值作为print语句的输入。相反,它不得不发出该字段的字段读取指令,该指令需要额外的字节,如前所述。这次,如果使用反射更改了字段的值,则调用hello方法也将打印更新的值。
虽然这是一个人为的例子,但是不难想象,在实践中如何用经典方法限制Java中的常量呢?如Math.max(CONST_A, CONST_B) 在编译的时候最大值本身就是常量,但是由于编译器无法对方法进行预估,因为也不能被编译器发现,哦!!这里原来是个常量哦!

局部变量类型推断 var

如下图,但是需要注意的是var并不是一个关键字,var仅仅是一个语法上的改进,在编译时期便已经将var转换为了对应的变量类型。然而在使用var定义变量时,必须立刻赋值,编译器能根据右边的表达式自动推断类型,所以var只是用来减少代码量的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值