背景
1991 年,James Gosling 带领团队开始了一个叫"Oak"的项目,这个就是 Java 的前身。1995 年,Java1.0 发布。“Write once, run anywhere"这句 Java 口号想必大家耳熟能详。Java 刚开始出现的时候主要面向 Interactive Television 领域,直至后来几年的发展,当时的 SUN(后来在 2010 年被 Oracle 收购)一度想用 Java 来打造桌面的网络操作系统,取代当时如日中天的 Windows。不过 Java 后来的发展,不曾想虽未在桌面领域内取得多大的建树,出乎意料地,却在企业级应用领域开花结果,占据了如今几乎统治的地位。失之東隅,却收之桑榆。
JavaSE 开源现状
Sun 在 2006 年的 Java One 大会上,宣布 Java 技术开源,随后 2006 年底在 GPL 协议下发布 HotSpot 以及 javac,这是 Java 发展中的里程碑事件。阿里巴巴最早在 2012 签署 OCA,并参与到了 OpenJDK 的开发。
OpenJDK 是 JavaSE 开源的 Reference Implementation。在 JavaOne 2017 的 Keynote 上 (2018 年 JavaOne 被 Oracle 重命名为 CodeOne),Oracle 承诺将开源所有的 OracleJDK 里包含的商业实现功能[1]。
在 2018 年发布的 Java11, Oracle 已经让 OpenJDK 和 Oracle JDK 两者的二进制文件在功能上尽可能相互接近,尽管 OpenJDK 与 OracleJDK 两者在一些选项之间仍然存在一些差异[2]。
另外,除了 OpenJDK 这条主线,在最近的几年里,Java 基础技术的开源有愈演愈烈趋势:2017 年,IBM 将内部使用 20 多年之久的 J9 虚拟机开源,并贡献到 Eclipse Foundation, 而随后 2018 年,Oracle 开源 GraalVM 1.0,其核心包含用 Java 写的Just-in-Time compiler/Graal, SubstrateVM 以及支持多语言解释器的 Truffle 框架。各个企业开源的主要动机,想通过开源构建并受益于一个更为强大的语言生态系统。
云 + 开源结合在一起,使得普通开发者以较低的门槛获得一流工具(链)的使用和体验,任何一家企业都可以像任何大型组织一样,使用的相同技术(democratizing),这是开发者的黄金时代。
Java is Still Free: 你该选择什么样的 JDK?
Java 仍然免费,但随着 OracleJDK License 变化开始转向收费,OpenJDK 会逐渐取代 OracleJDK 成为市场主流,这点也可以从 JVM 2020 生态报告中看出趋势:OracleJDK 从前一年的 70% 的开发者选择使用率降到 2020 年的 34%。
OracleJDK 收费,在客观上也加剧了 OpenJDK 生态的碎片化趋势,出现了包括 Alibaba Dragonwell 在内的多个基于 OpenJDK 的可选实现。
企业在选择使用那个 Java Vendor 的 JDK 版本时,几个方面的考虑因素可以参考:
- 安全与稳定:是否会及时同步上游的最新更新,包括安全补丁,关键的问题修复等。
- JavaSE 标准兼容 :是否与标准 Java 兼容。
- 性能与效率:是否可以在问题诊断,性能调优方面提供有效的工具支持,帮助一线的开发同学高效地解决 Java 问题。在 JVM,到 JDK (Class library) 层面,是否有面向企业业务场景的优化特性,可以帮助提升资源的利用率,生产系统的稳定性等等。
- 快速的新技术采纳:伴随收费,Oracle 管理 Java 版本生命周期采用了 Long Term Support(LTS) 的概念,Oracle 每三年会指定一个 LTS 的 Java 版本, Java 8/11 都是 LTS 版本。大部分企业,尤其是大中型企业很难跟上 Java 每六个月一发布的节奏,像 Java 12,13 这样的 Feature Release(FR) 版本。那么问题来了,如果你选择 Stay 在 LTS 版本上,比如 Java 11,在新版本 (Java11+) 发布的 JVM/JDK 技术,是否可以在不升级的情况下,提前享受这些技术红利?
这里分享下 Alibaba Dragonwell 在这些方面的计划与思考。
Alibaba Dragonwell 是阿里巴巴内部广泛使用的 AJDK (AlibabaJDK) 的开源版本,Alibaba Dragonwell 作为基石,支撑了阿里经济体内几乎所有的 Java 业务,经过了双 11 等大促的考验。Alibaba Dragonwell 主要针对的场景是数据中心大规模 Java 应用部署情况下,Java 应用稳定性、效率以及性能的优化与提高。
2019 年 3 月阿里开源 Alibaba Dragonwll 8.0.0,我们也一直正在践行开源时候的承诺,AJDK 内部使用的特性在逐步开源。到刚刚发布 Alibaba Dragonwell 8.3.3,我们已经开源了 JWarmup,ElasticHeap,多租户,JFR 等众多功能,协程 Wisp 2.0,GCIH 等也在开源的规划上。
同时,Alibaba Dragonwell 作为 OpenJDK 的下游,每个发行版都会同步上游最新更新,包括安全更新,问题修复等,并经过阿里内部大规模的应用集群测试。
在新技术 Adoption 方面,Alibaba Dragonwell 目前发布和维护了 Java 8,11 两个 LTS 版本,阿里 JVM 团队会根据实际业务状况,移植 Java11+ 的相关功能到 Java 8 和 11 两个版本,这样 Alibaba Dragonwell 用户可以在不跟进 Java 12,13 等这些 FR 版本的情况下,提前享受这些功能带来的技术红利。
OpenJDK技术趋势
纵观 Java 技术 20 多年的发展,始终围绕着两大主题:Productivity 以及 Performance。在很多情况下,Java 在设计上 Productivity 是优于 Performance 考虑的。Java 引入的 Garbage Collector 把程序员从复杂的内存管理中解脱出来,但在另一方面 Java 应用始终困扰于 GC 暂停时间的影响。Java 基于栈式虚拟机的中间字节码设计,很好地抽象了不同平台 (Intel, ARM 等) 的差异性,同时通过 Just-in-Time (JIT) 编译技术,解决的 Java 应用 peak 性能, 但在另一方面 JIT 不可避免引入了 Warmup 的代价,正常情况下 Java 程序永远需要先 load class,解释执行,然后再到高度优化的代码执行。
如果从 JVM 视角来总结梳理下目前 OpenJDK 社区正在发生,孵化的相关技术,主要从工具,GC,编译器,以及 Runtime 四个方面进行一个主要概括:
JFR/JMC
Oracle 从 Java 11 开源了其之前一直作为商业功能的 JFR,JFR 是功能强大的 Java 应用问题诊断与性能剖析工具。阿里巴巴也是作为主要的贡献者,与社区包括 RedHat 等,一起将 JFR 移植到了 OpenJDK 8, 预计 2020 年 7 月即将发布的 OpenJDK 8u262 (Java8) 将会默认带有 JFR 功能,这样 Java 8 的用户可以基于这个版本免费使用 JFR 功能。
ZGC/Shandoath
无论是 Oracle 在 Java 11 发布的 ZGC,还是 RedHat 已经做了好几年的 Shandoath,都实现了 concurrent copy GC,解决 Large Heap 情况下的 GC 停机性能。ZGC 最新状态,在 9 月份即将发布的 JDK 15,ZGC 将从 Experimental 功能变为生产可用 [3] 。实际上,在 AJDK 11 上,阿里巴巴团队 JVM 团队已经做了大量 Java 11+ 到 Java 11 的 ZGC 移植工作,以及相关问题修复,2019 年双 11 和阿里数据库团队一起,让数据库应用运行在 ZGC 上,100+ GB Heap 情况下 GC 暂停时间可以保持在 <10ms 以内, 详细讨论参考[4]。
Graal
用 Java 开发的新一代 Just-in-Time 编译技术,用来替代目前 HostSot JVM 的 C1/C2 编译器,OpenJDK 上的 Ahead-of-Time (AOT) 技术也是基于 Graal 编译器开发。
Loom
OpenJDK 社区协程项目,对应于 AJDK 的 Wisp 2.0 实现,详细讨论可以参考[5]。
进击的 Java:面向未来演进
2020,站在一个全新的节点上,本文也从三个大的方面 Cloud Native, AI,以及多语言生态三个方面展望下未来的发展,有些讨论本身是超越 Java 本身的。
面向 Cloud Native 的语言进化
云原生时代,软件的交付方式发生的根本性变化。以 Java 为例,在之前 Java 开发者交付的是应用本身,具体体现在以 "jar", "war" 的形式交付, 而云原生则是以 Container 为交付单位的:
在运行方面,面向 Cloud Native 的应用要求:
- Reactive
- Always Watching
- Extreme low memory footprint
- Quick boot time
Java 语言作为企业计算,互联网领域的王者,拥有一致性,丰富的构建在 Java 语言之上的生态系统, 丰富的三方库,多样的 Serviceability 支持等,随着云时代应用微服务化,Serverless,这些新的架构逐渐触及到了 Java 程序速度提升的天花板 —— Java 自身的启动运行开销。
在 Cloud Native 这个新的上下文里, 我们谈论语言的进化,绝不仅仅限于运行时,编译器层面, 新的计算形态一定伴随着编程模型的变革,这涉及围绕程序语言的 Library,Framework,Tools 等一系列配套的改革。从目前业界来看,也有不少的项目正在发生:配合 GraalVM/SVM (Java 静态编译技术) 的下一代编程框架 Quarkus, Micronaut, 以及 Helidon,Quarkus 更是提出了“container first” ,他们提倡的分层的 lightweight uber-jar 的概念正是符合了 container 交付这一趋势。而 Red Hat 的 Java 团队与 OS 团队合作的"Checkpoint Restore Fast Start-up"技术 (AZul 在 JVM 技术峰会 '2019 上也提出过类似的想法) 则是在更加底层的技术栈上解决 Java 快速拉起问题。
在 Java for Cloud Native 方向,我们也开展了相关研发工作。Java 是静态语言,但是包含了大量的动态特性,包括反射,Class Loading,Bytecode Instrument (BCI) 等等,这些动态特性本质上都是违反 GraalVM/SVM 所要求的 Closed-World Assumption (CWA) 原则,这也是导致传统跑在 JVM 的 Java 应用不容易在 SVM 编译运行的主要原因。阿里巴巴 JVM 团队对 AJDK 做了静态化裁剪,务求在 Java 静/动态特性之间找到一个确定的边界,从 JDK 的层面为 Java 静态编译提供可能性。同时向上,与蚂蚁中间团队合作,定义面向静态编译的 Java 编程模型,通过编程框架来约束 - Java 应用的开发是面向静态编译友好的。我们静态编译了基于蚂蚁开源中间件 SOFAStack 构建的服务注册中心 Meta 节点应用,相较于传统 的运行在 JVM上,性能有量级的提升:服务启动时间降低了 17 倍,可执行文件大小降低了 3.4 倍,运行时内存降低了一半。详见[6]。
AI 的兴起,编程语言异构计算的新挑战
2005 年,时任 Intel CTO 的 Justin Rattner,说过 “We are at the cusp of a transition to multicore, multithreaded architectures”, 在前后的十几年中, 编程语言与编译器领域一直在努力面向 parallel architectural paradigm 做优化探索。随着 AI这些年的兴起, 不同的时间节点,相似的场景,面向 FPGA/GPU 异构计算场景,对编程语言与编译器领域提出了新的挑战。
除了传统 Compiler 诸如 IBM XL Compilers, Intel Compilers 等做的 Automatic Parallelizing 工作,在极致性能探索方面,基于多面体模型 (polytope model) 的编译优化技术作为解决程序并行化、数据局部性优化的一种手段,成为编译优化领域的研究热点。
而在 Parallel Languages 层面,对 C&C++ 开发人员,CUDA 的出现降低了 GPU 的编程门槛,但 GPU 和 CPU 两种硬件模型本质区别,导致过高的开发成本,需要学习和了解更多底层硬件细节,还更不用说更高级语言的开发语言像 Java 等所面临的底层硬件模型与高级语言之间巨大的 GAP。
在 Java 领域,最早在 JVM 技术峰会 '2014,AMD 曾经分享过他们的 Sumatra 项目,尝试实现 JVM 与 Heterogeneous System Architecture 目标硬件交互。而在最近,由 The University of Manchester 发起的 TornadoVM 项目,实现包含:一个 Just-in-Time 编译,支持从 Java bytecode 到 OpenCL 的映射,一个优化的运行时引擎,以及可以保持 Java 堆和异构设备堆内存一致性的内存管理器。TornadoVM 的目标是开发人员不需要了解 GPU 编程语言或者相关的 GPU 体系结构知识就可以编写面向异构的并行程序。TornadoVM 可以透明地运行在 AMD GPUs, NVIDIA GPUs, Intel integrated GPUs 以及 multi-core CPUs 上。
在通用 CPU 领域, OpenJDK 社区的 Vector API 项目 (Panama 的子项目),依赖 CPU 的 SIMD 指令,获得计算性能的成倍提升,Vector API 在大数据,AI 计算也有非常广的应用场景。阿里 JVM 团队把 Vector API 移植到了 AJDK 11,后续会开源到 Alibaba Dragonwell,分享下我们获得的基础性能数据:
时间 (单位: milliseconds) 越短,性能越好
Polyglot Programing,链接多语言生态
Polyglot Programming 并不是一个新的概念。在 Managed Runtime 领域, 2017 年 IBM 开源 Open Managed Runtime(OMR), 以及 2018 年 Oracle 开源 Truffle/Graal 技术。OMR 和 Graal 技术让开发人员实现一个新的语言成本大幅下降。前者 OMR 以 C、C++ 组件的形式提供了 Garbage Collection (GC), Just-in-Time (JIT) 以及 Reliability, availability and serviceability (RAS,工具)等, 开发人员可以依赖这些组件,通过 'glue' 的方式基于这些组件实现自己的高性能语言。而后者 Truffle/Graal, Truffle 是一个依赖 AST parser 实现新的语言的 Java 框架,本质上是将你的新的语言映射到 JVM 世界。不同于 Scala, JRuby 这些围绕 JVM 生态本身构建的语言,他们本质是还是 Java, 无论是 OMR, 还是 Truffle/Graal,他们都提供了生产级的 GC,JIT,以及 RAS 服务支持,新开发的语言完全不需要再重新实现这些底层技术。
从业界来看,面向特定领域的 Domain Specific Language (DSL) 语言已经有向这些技术迁移的趋势,高盛正在与 Graal 社区合作,把他们的 DSL 迁移到 Graal 上。另外 Ruby/OMR, Python/Graal, JS/Graal,WASM/Graal 等这些真正链接不同语言生态的项目,也正在迅速发展起来。
回到 AJDK, Graal 已经在 AJDK 8 开始支持, JS/Graal 这样成熟的技术,已经在阿里内部业务上线。
最后
Java 是一项二十多年前被发明出来的技术,她历经磨难,几易其主,但却历久弥新。这篇报告旨在为 Java 的开发者们梳理下目前的 Java 技术现状,以及讨论在云,AI 等这些重要领域内 Java 技术的演进趋势。在介绍的相关部分,我们也穿插了阿里的一些工程实践。作为世界上最大的 Java 用户之一,我们也一直在探索把前沿的 Java 技术,通过在阿里丰富的业务场景的试验,真正把这些技术应用于真实的生产环境。我们也非常乐于分享和贡献 Java 领域的经验、实践与技术洞见,共同促进 Java 的发展。
参考[1]https://www.infoq.com/news/2017/10/javaone-opening/
[2]https://openjdk.java.net/jeps/377
[3]https://mp.weixin.qq.com/s/FQpvT5wIy9xwhX2jHMU7aw
[4]https://mp.weixin.qq.com/s/K1us6aH-gjHsWGhQ3SulFg
[5]https://www.infoq.cn/article/uzHpEbpMwiYd85jYslka