自从三年前发布以来,GraalVM已经引起了Java开发的一场革命。GraalVM讨论最多的特性之一是原生映像,它基于超前(AOT)编译。它释放了本地应用程序的运行时性能,同时保持了熟悉的开发人员生产力和Java生态系统的工具。
原生映像如何工作?
Graal编译器也作为提前(AOT)编译器工作,产生本机可执行文件。考虑到Java的动态特性,它到底是如何工作的呢?
与编译和执行同时发生的 JIT 模式不同,在 AOT 模式下,编译器在构建期间执行所有编译,然后再执行。 这里的主要思想是将所有“繁重的”——昂贵的计算——转移到构建时间,所以它可以完成一次,然后在运行时生成的可执行文件快速启动并从一开始就准备好,因为一切都是预先计算的并预编译。
GraalVM 'native-image' 实用程序将 Java 字节码作为输入并输出本机可执行文件。为此,该实用程序在封闭世界假设下对字节码进行静态分析。 在分析过程中,该实用程序会查找您的应用程序实际使用的所有代码,并消除所有不必要的代码。
这三个关键概念有助于您更好地理解原生映像生成过程:
分析要点。GraalVM本机映像确定哪些Java类、方法和字段在运行时是可访问的,并且只有那些将被包括在本机可执行文件中。点到点分析从所有的入口点开始,通常是应用程序的主要方法。分析迭代地处理所有可传递到达的代码路径,直到到达一个固定点,分析结束。这不仅适用于应用程序代码,也适用于库和JDK类——将应用程序打包成自包含二进制文件所需的一切。
构建时的初始化。GraalVM原生映像默认在运行时进行类初始化,以确保正确的行为。但是如果原生映像可以证明某些类初始化是安全的,它将在构建时初始化它们。这使得运行时初始化和检查变得不必要,并提高了性能。
堆快照。原生映像中的堆快照是一个非常有趣的概念。在映像构建过程中,静态初始化器分配的Java对象以及所有可访问的对象都被写入映像堆。这意味着使用预填充的堆,您的应用程序可以更快地启动。
与JVM不相上下的最高性能
但是,峰值性能如何呢?当一切都提前编译时,原生映像如何优化运行时的峰值吞吐量?
我们正在努力确保原生映像提供出色的峰值性能和快速启动。已经有几种方法可以提高原生可执行文件的峰值性能:
按配置优化。由于原生映像提前优化和编译代码,因此在应用程序运行时,默认情况下它无法访问运行时分析信息来优化代码。解决这个问题的一种方法是使用配置文件导向优化(PGO)。使用PGO,开发人员可以运行应用程序,收集分析信息,然后将其反馈到原生映像生成过程中。“原生映像”实用程序使用这些信息,根据应用程序的运行时行为来优化生成的可执行文件的性能。
原生映像中的内存管理。由原生映像生成的可执行文件中的默认垃圾收集器是串行垃圾收集器,这对于具有小堆的微服务来说是最佳的。
原生影像的未来
自第一次公开发布以来,原生图像已经向前迈出了巨大的步伐。它被Java框架广泛采用,云供应商提供原生映像作为运行时,并且许多库使用开箱即用的原生映像。
领取专属 10元无门槛券
私享最新 技术干货