静态Java当前状态:编译的本地可执行文件的启动速度和占用空间小

101 阅读6分钟

静态Java现状:编译的本地可执行文件的启动速度和占用空间小

Static Java产生了静态编译的本地可执行文件,目标是快速启动和占用空间小,在磁盘上和运行时的元数据开销都很低。InfoQ采访了Red Hat的首席软件工程师Dan Heidinga,他是静态Java工作的长期贡献者,以了解我们离广泛的采用还有多远。

他对Static Java的参与是由于认识到Java需要发展以满足与云有关的新实践所驱动的不断变化的生态系统。除了他目前在OpenJDK的Project CRaCOpenJ9的CRiU中参与的CRiU(用户空间的检查点/恢复),以及他对OpenJ9 JVMJava Lambdas、将方法句柄引入Java和目前的Project Valhalla的贡献,他在实现静态Java的过程中拥有一个前排座位。

InfoQ:你好,Dan。感谢你抽出时间来回答我们读者的几个问题。能否请你简单介绍一下自己,说明你的日常职责以及你对Static Java的参与?

Dan Heidinga:我 是一个长期的JVM开发者和Java用户。我的日常职责是在Hotspot JVM上工作(也是OpenJ9那个JVM的项目负责人),并参与qbicc项目:一个实验性的Java程序静态编译器,它作为你的游乐场,尝试不同的静态Java方法,帮助探索完整的设计空间,为OpenJDK的Project Leyden做准备。

我还积极参与了OpenJDK的Project CRaC和OpenJ9的CRiU项目中的CRiU(用户空间中的检查点/恢复)调查,因为我看到检查点/恢复和静态Java的需求有很多重叠之处。

InfoQ:静态Java的好处是什么?什么是最适合它的用例?

Heidinga。静态Java会产生一个静态编译的本地可执行文件,目标是快速启动和占用空间小,在磁盘上和运行时的元数据开销都很小。尽管可以使用它的潜在场景有很多,但微服务、CLI应用和无服务器部署是最合适的人选。

它是由少量的能力组成的:

  • 原生编译构成你的应用程序的所有Java代码。
  • 能够 "关闭世界",防止额外的类被加载。这允许死代码消除,删除不使用的方法和字段,从而使二进制文件更小。
  • 能够在构建时初始化应用程序的某些部分,以便进一步优化,并避免在随后的启动中进行多余的工作。

主要的好处是可以从一个小的、单一的可执行的部署包中快速启动。更快的启动来自于能够避免Java的动态行为,如加载和验证类,并在第一次使用时解决每个字段和方法。还有就是使用构建时的初始化,将操作(如类的初始化)从运行时转移到构建时。

运行时的足迹改进对于具有小堆的应用来说是最明显的,因为否则的话,堆的大小会完全支配类元数据所需的较小的内存。

InfoQ:要从Java的经典 "动态虚拟机 "模型迁移到静态Java,对开发者有什么要求?

Heidinga。即使有了指南和工具,开发者也应该花费相当多的精力来解决将他们的应用转变为静态应用的难题。

静态Java,顾名思义,比普通Java的动态性要低得多,因此使用Java的许多动态功能,如反射、方法句柄、类加载、字节码生成和JVMTI代理,会导致问题。一个好的开始是GraalVM的跟踪代理,创建支持运行时使用这些动态功能所需的配置文件。静态Java的要求之一--动态功能变得更加有限,需要在构建时明确选择进入。

选择一个使用Static Java的框架(如Quarkus、Micronaut)将使你能够利用它的优势,而不会有采用时的障碍。

InfoQ:Static Java已经在生产系统中使用了吗?

Heidinga: 早期的采用者在生产中使用它,但主要是在绿地项目或非关键用例上,以便让他们建立信心和知识。我希望OpenJDK的Project Leyden模型的标准化将有助于采用。现在,静态Java,除了框架使采用的道路更加顺畅之外,仍然很难开始使用。

虽然我预计随着云计算实践不断占领行业,以及用户对云计算部署的成本意识增强,采用率会继续增长,但增长速度会很慢,因为有很多软件永远无法适应静态Java的要求(这也没关系!)。需要其特性的用户才刚刚开始意识到这些功能对他们的部署有多重要。

为了真正推动主流的采用,Java需要意识到阶段性的变化(构建时间与运行时间以及检查点与恢复),并给开发者提供工具,让他们在语言中说出自己的意思。我认为这即将到来,但考虑到现有的OpenJDK项目的时间框架,这可能需要一年多的时间。

Heidinga认为,随着云计算的不断发展,以及对更快的启动时间和更小的足迹的需求,静态Java只是在其旅程的开始。但是Project Leyden的实施可能会加速它的采用。然而,在这个阶段,他建议对其进行实验,并指出由红帽公司的杰出工程师Andrew Dinn领导的实验。海丁格还坚持认为,很难说莱顿项目自2020年批准以来取得了多少进展,但是。

很多调查和探索正在OpenJDK和周围的社区发生,希望我们能在不久的将来看到这些在Project Leyden中汇集起来。

有几个项目与Leyden的问题空间有重叠,比如来自CRaC项目,特别是关于 "如何暴露Java编程模型的不同阶段"。另外,GraalVM社区在这段时间里也在继续改进SubstrateVM

对于那些在采用静态Java时遇到无法解决的问题,或者只是不想调整现有的动态设计的人来说,仍然有希望更快地启动:CRiU相关的努力,如Project CRaC,来探索静态和动态Java之间的另一个点。