@pockry
2017-09-19T09:10:57.000000Z
字数 4087
阅读 2037
Java
作者:杨晓峰
作者介绍
2011年加入Oracle北京研发中心Java团队,Principal Member of Technical Staff, OpenJDK Committer,目前领导Java核心类库北京团队,主要负责Java 9核心类库新特性相关任务。个人兴趣主要专注于Java以及其他编程语言的新特性,尤其是在云计算等前沿领域的应用和演进。
针对Java 9新特性的介绍已经非常多了,我这里不想再做一个百科全书一样的列表,希望从不同角度简要点评部分特性。
首先,谈到Java 9大家往往第一个想到的就是Jigsaw项目,这是一个雄心勃勃的项目。
大家知道,Java已经发展超过20年(95年最初发布),Java和相关生态在不断丰富的同时也越来越暴露出一些问题,比如Java运行环境的膨胀和臃肿,各种类库和工具在提供强大功能的同时,也越来越复杂,不同版本的类库交叉依赖导致Jar Hell等让人头疼的问题,这些都阻碍了Java开发和运行效率的提升。
但是由于兼容性等各方面的掣肘,对Java进行大刀阔斧的革新越来越困难,Jigsaw从Java 7阶段就开始筹备,Java 8阶段进行了大量工作,终于在Java 9里落地,有种千呼万唤始出来的意味。
Jigsaw项目的目标是改进Java SE平台,使其可以适应不同大小的计算设备;改进其安全性,可维护性,提高性能;简化各种类库和大型应用的开发和维护。
这个项目的工作量和难度大大超出了初始规划。JSR 376 Java平台模块化系统(JPMS, Java Platform Module System)作为Jigsaw项目的核心,其主体部分被分解成6个JEP(JDK Enhancement Proposals)
可以看到这是一个庞大的系统工程,Java的方方面面,包括JDK编译工具,运行时,Java公共API和私有代码等等,完全是一个整体性的改变。
随着Java平台模块化系统的落地,开发人员无需再为不断膨胀的Java平台苦恼,例如,您可以使用jlink工具,根据需要定制运行时环境。这对于拥有大量镜像的容器应用场景或复杂依赖关系的大型应用等,都具有非常重要的意义。
从软件开发实践的角度,Java语言层面提供对模块的支持,可以鼓励(当然在某种程度上也可以看作强制)更加规范的开发实践,利用业界在开发领域几十年的经验、教训总结出的最佳实践,促进Java生态的健康发展。比如,更加完善的隐藏实现细节,这不仅可以促进面向接口、约定的编程,也可以避免可能的安全风险等。
不过,换个角度来说,天下没有免费的午餐,由于JPMS是语言平台层面的支持,它并不是完全透明的,也就是说不管用户是否真的需要或从中收益,都会或多或少的受其影响。
对此,我们可以从JPMS评审中针对类似深度反射限制之类的激烈争吵中,深刻体会到。比如,针对反射访问控制,最终Java 9开发团队,采取了相对折中的办法,在反射领域默认保持Java 8的默认行为。Java 9在兼容性方面,相比于过往的版本,采取了更大的容忍度。
不过,Java 9的相当一部分特性仍然是对用户透明的。只要升级到Java 9,不需要或者很少需要用户参与动作就能获益。比如,更加紧凑的字符串实现;改进的竞争锁机制;改进安全应用性能 ;利用特定CPU指令优化GHASH和RSA等等,这些都是开箱即用、触手可得的改进。
对于部分开发者来说,探究Java内部API或者平台底层能力是一件非常酷的事情,但这往往并不是非常容易,比如部分能力可能并没有在历史版本的公共API中暴露出来(比如Unsafe相关),或者需要特定领域的知识。在Java 9中,不要错过JEP 193: Variable Handles和JEP 274: Enhanced Method Handles,JEP 259: Stack-Walking API,JEP 285: Spin-Wait Hints等特性。
另外,Java 9中还有很多承上启下的特性,为未来创新打下基础或者整合、规范现有碎片化的功能,我会介绍一些有代表性的新特性。
在Java虚拟机领域,JEP 271: Unified GC Logging和JEP 158:Unified JVM Logging,对各种JVM日志进行了统一,大家终于不用为各种碎片化的日志选项苦恼了。
Oracle一直在努力提高Java启动和运行时性能,希望其能够在更广泛的场景达到或接近本地语言的性能。但是,直到今天,谈到Java,很多C/C++开发者还是会不屑地评价为启动慢,吃内存。
简单说,这主要是因为Java编译产生的类文件是Java虚拟机可以理解的二进制代码,而不是真正的可执行的本地代码,需要Java虚拟机进行解释和编译,这带来了额外的开销。
JIT(Just-in-time)编译器可以在运行时将热点编译成本地代码,但是实际应用可能非常庞大,大型Java应用的预热往往非常耗时,而且非热点代码可能根本没有机会被JIT编译。
在JDK 9中, AOT(JEP 295: Ahead-of-Time Compilation)作为实验特性被引入进来,开发者可以利用新的jaotc工具将重点代码转换成类似类库一样的文件,这样会大大降低启动开销。
另外JVMCI (JEP 243: Java-Level JVM Compiler Interface)等特性,对于整个编程语言的发展,可能都具有非常重要的意义,虽然未必引起了广泛关注。目前Graal Core API 已经被集成进入Java 9,虽然还只是初始一小步,但是完全用Java语言来实现的可靠的、高性能的动态编译器,似乎不再是遥不可及,这是Java虚拟机开发工程师的福音。
与此同时,随着 Truffle框架和Substrate VM的发展,已经让个别信心满满的工程师高呼“One VM to Rule Them All!”, 也许就在不远的将来Ploygot以一种另类的方式成为现实。
前面简短地谈了谈Java 9中的一些令人激动的特性,Java 9在取得这些进步的同时,那么在其的研发过程中有哪些教训,当前和未来遇到了那些挑战呢?
首先,就是如何更加快速、敏捷地进行创新。在Java 9的开发过程中,非常突出的一点就是,由于Jigsaw项目的延期,导致Java 9的发布一再推迟,这带来了很多负面影响。大批特性已经完成多时,却无法及时被实际应用采纳,开发者无法及时地从中获益,也很难尽早发现和反馈可能存在的问题或改进。这不禁让人反思Java传统的研发模式的局限性。
针对这些情况,Java首席架构师Mark Reinhold已经发出倡议,建议从传统的以特性驱动的发布周期,转变为以时间驱动的(6个月为周期)发布模式,并逐步的将Oracle JDK原有商业特性进行开源,Java Flight Recorder等杀手级工具和特性,一定会大受开发者的欢迎。针对企业客户的需求,Oracle将以三年为周期发布长期支持版本(long term support)。
第二,随着云计算和AI等技术浪潮,当前的计算模式和场景正在发生翻天覆地的变化,不仅对Java的发展速度提出了更高要求,也深刻影响着Java技术的发展方向。传统的大型企业或互联网应用,正在被云端,容器化应用、模块化的微服务甚至是函数(FaaS, Function-as-a-Service)所替代。
Java需要在新的计算场景下,改进开发效率。这话说的有点笼统,我谈一些自己的体会,Java代码虽然进行了一些类型推断等改进,更易用的集合API等,但仍然给开发者留下了过于刻板、形式主义的印象,这是一个长期的改进方向,例如,JEP 286: Local-Variable Type Inference;持续改进并发计算框架,Java的并发特性非常强大和系统,但某种程度上过于复杂,在今年的JVMLS上,阿里巴巴AJDK组介绍了利用协程改进并发的实践,这是一个令人眼前一亮的创新;Java非常需要更加友好的本地代码支持,相关的特性有很多好的想法和尝试,比如Panama项目;Value Types和改进的泛型,有兴趣可以参考Valhalla项目。
最后,进一步改进启动和运行性能、优化计算资源使用。目前,相当一部分的Java类库和虚拟机特性都是针对长时间、大数据量、高并发等复杂任务进行的优化,但是在部分云计算场景中,比如越来越引起大家关注的FaaS应用,短时间、无状态的函数正在成为常见的计算单元。那么在这种场景下,Java必须进行相应的改进和创新,才能保持和强化目前在软件开发领域的竞争力。比如,提高Java运行时启动速度,尤其是在容器环境的初始化表现;保证CPU等计算资源调度能力能够适应容器环境的新情况,最直接的就是Java平台需要支持基于cgroup等技术的资源管理;针对新场景下的GC优化;如何提高数据密度和计算效率等等。
以上很多方面往往不是孤立的,也不是非常简单就可以完成的,很多改进都是依赖于相关语言基础技术的进步和突破,Java的进步需要持之以恒的耐心和持续的努力与投入。
最后,欢迎大家能够参与到OpenJDK社区,Java是大家的,欢迎您向OpenJDK提供建议、意见或者直接提交自己的改进,在社区中听见越来越多的来自中国的声音是非常令人高兴的事情,让我们携手促进Java的创新和发展。
延伸阅读:
InfoQ一直关注Java的发展,我们也对Java 9的一些新特性进行了跟进报道,欢迎查看我们以往对Java 9的报道。