【譯】Oracle GraalVM 發(fā)布,啟動快了46.42%
一、Oracle GraalVM
Oracle GraalVM 是一個新 GraalVM ?的發(fā)行版,它適用于JDK 17和JDK 20,并在GraalVM 免費條款和條件(GFTC)許可證下發(fā)布(請參見FAQ)。這意味著你可以免費使用所有最優(yōu)秀的GraalVM功能,無論是在開發(fā)中還是生產環(huán)境!
對于Native Image,在這個版本中引入了以下特性:
Profile-guided 優(yōu)化 和更多編譯器優(yōu)化,以獲得最佳的峰值性能 G1 GC用于運行具有大堆和最小暫停時間的應用程序 壓縮對象頭和指針,以獲得更低的內存占用 機器學習自動推斷分型信息 支持SBOM的附加安全功能
GraalVM Native Image 已經因其即時啟動而聞名,但是隨著這個版本的發(fā)布,我們可以展示它也是一種非常高效的方式來運行長時間運行的Java應用程序,且性能高。我們已經在使用GraalVM Native Image編譯的一個Java 20 Spring PetClinic 示例應用程序上進行了測試,并與JIT編譯進行了比較,以下是性能結果:
使用 Oracle GraalVM Native Image、GraalVM CE Native Image 和帶有 C2 JIT 的 GraalVM CE 的 Spring Petclinic 性能。基準測試實驗在 Oracle X5-2 服務器(Intel Xeon E5-2699 v3)上運行了最新的 Spring Petclinic,將工作負載限制在16個CPU,并設置了最大堆大小為1GB。使用wrk測量最大吞吐量,以循環(huán)方式擊中五個不同的端點(創(chuàng)建寵物、所有者和診所訪問并讀取所有者和寵物ID),每秒600個請求,在100秒內進行。峰值吞吐量是以下180秒的平均性能。延遲數字是在吞吐量實驗完成后捕獲的,使用 wrk2應 用每秒5000個請求的恒定負載。
現在讓我們更仔細地看一下這些性能指標。
Native Image 以啟動速度快而聞名。由于使用 Oracle GraalVM 的額外編譯器優(yōu)化,啟動將提升到一個新的級別:
相對于GraalVM CE Native Image,Oracle GraalVM Native Image的啟動速度**快46.42%**。 啟動速度比在JIT上運行(GraalVM CE with C2 JIT)快32倍。
由于使用了額外的內存優(yōu)化,使用 Oracle GraalVM Native Image 構建的應用程序使用內存顯著減少:
相對于GraalVM CE Native Image,少25%的內存。 相對于GraalVM CE with C2 JIT,少2.52倍的內存!
在這里,Oracle GraalVM Native Image 的峰值吞吐量比 GraalVM CE 高 1.6 倍。對于這個特定的應用程序,吞吐量仍略低于 JIT。當在 Spring、Quarkus 和 Micronaut 等其他基準測試中運行時,在許多情況下,我們看到 AOT 在峰值吞吐量方面甚至領先于JIT。
另一個評估您的應用程序重要的指標是效率:在給定的時間和資源量下可以獲得多少性能。這在云端尤為重要,因為您需要支付資源的費用以及使用它們的時間長度,但即使在本地環(huán)境中,您也希望高效地利用基礎設施。為了評估這一點,讓我們看一下我們的應用程序可以每秒處理多少個請求,每GB內存(參見上圖):
Oracle GraalVM Native Image 可以每秒處理 14780 個請求/GB/s,是CE Native Image 和 C2 JIT 的兩倍。
這意味著使用 Oracle GraalVM Native Image,您可以獲得適合您基礎設施的最佳峰值吞吐量,或在資源受限的環(huán)境中實現良好的性能。現在讓我們來看一下延遲分布。延遲是反映應用程序所有請求響應能力的關鍵指標。最慢的請求在尾延遲分布中可見,并且極大地影響著服務質量。通常,業(yè)務需求規(guī)定大多數請求的特定延遲限制(通常是99%,即P99延遲)。
在這里,我們可以看到在95個百分位之前,Oracle GraalVM Native Image 和 CE JIT with C2 有著非常相似的響應時間,均低于3毫秒。這意味著您可以期望使用本地鏡像與JIT相同的應用程序響應性。然而,在最高百分位數上,JIT 的響應時間明顯下降,而 Native Image 的響應時間保持較低。因此,對于這個應用程序來說,Native Image 提供了明顯更好的 P99 延遲時間,因此提高了服務的響應性。綜上所述,Oracle GraalVM Native Image 為長時間運行的應用程序提供了出色的性能特征,同時具有快速啟動和低資源使用的優(yōu)點。我們還在此版本中推出了許多新功能。由于更新涵蓋范圍廣泛,我們發(fā)布了兩篇博客文章:本篇博客側重于 GraalVM JDK 和 Native Image,另一篇則涵蓋了 GraalVM 語言和 Truffle 的更新。現在,讓我們看看此版本中還有什么新內容!
二、基于 JDK 17 和 JDK 20 構建的 GraalVM
GraalVM 現在有一個與 JDK 版本命名相匹配的新命名方案 - 例如,這個版本包括兩個 GraalVM 版本:GraalVM for JDK 17 和 GraalVM for JDK 20。這兩個版本都基于主分支,并包含新功能,因此您可以選擇最適合您的JDK版本。然而,我們建議您轉移到JDK 20 - 正如我們之前宣布的那樣,我們正在過渡到一個新的發(fā)布計劃,在這個計劃中,我們將只為最新的 Java 版本發(fā)布 GraalVM(就像 Oracle JDK 一樣)。這樣,您也可以同時使用所有最新的 Java 和 GraalVM 功能。本次發(fā)布的另一個重大更新是 GraalVM JDK 下載現在包括 Native Image!不需要將 Native Image 作為單獨的組件下載或運行 gu install native-image,它一開始就已經準備好了。下載 Oracle GraalVM 也變得更加容易,我們現在有穩(wěn)定的可腳本化下載 URL,因此您可以直接使用它們進行下載,或者在您的腳本和Docker文件中使用。例如,要在Linux x86-64上獲取適用于JDK 20的Oracle GraalVM,請運行以下命令:
wget?https://download.oracle.com/graalvm/20/latest/graalvm-jdk-20_linux-x64_bin.tar.gz
三、基于機器學習的編譯優(yōu)化
Oracle GraalVM 中可用的一個非常有用的功能是基于配置文件的優(yōu)化(PGO)。PGO 使您能夠在運行時收集應用程序的性能分析信息,然后與 Native Image 一起使用,以優(yōu)化生成的本地可執(zhí)行文件的性能。它使您能夠將 AOT 優(yōu)化的優(yōu)點與運行時性能分析相結合使用。此版本中一個令人興奮的新功能是基于機器學習的自動分析。Native Image 現在使用預訓練的 ML 模型來預測控制流圖分支的概率。然后,我們使用預測的概率進行 PGO。在諸如 Renaissance、Da Capo 和 Da Capo con Scala 等全面基準測試中,由預測配置文件推動的 PGO 相比于默認的 Native Image 配置可提供約 6% 的運行時加速。基于 ML 的配置文件分析在 Oracle GraalVM 中可用,并默認啟用,我們期待您的反饋和性能報告。但是,請記住,ML 配置文件推斷可能會略微增加本地可執(zhí)行文件的大小,約1-2%。
四、更高性能的 Native Image
編譯器提供更好性能的一種方式是利用部署平臺的體系結構特定功能。使用這些特定功能可以提供更好的性能,但在部署到沒有這些特定指令的機器上時可能會出現兼容性挑戰(zhàn)。我們引入了一個新的 **-march** 選項,類似于gcc,它可以讓您在平臺特定性能和兼容性之間進行選擇:-march=compatibility 提供最佳兼容性,或者 -march=native 提供最佳性能,如果本地可執(zhí)行文件部署在相同的機器架構或具有相同CPU特性的機器上。要列出所有可用的機器架構,請使用 -march=list。我們還對基于配置文件的優(yōu)化進行了幾個更改:
為了為應用程序提供最佳的峰值性能,PGO需要完整的剖析信息。這意味著您可能需要多次運行您的應用程序,并使用不同的工作負載來確保所有的用例都被剖析。現在,通過 native-image-configure可以合并多次PGO運行收集的剖析文件。基于配置文件的優(yōu)化現在有一個新的采樣分析器,可以收集調用堆棧。此數據隨后包含在一個.iprof文件中。當構建有PGO儀器的可執(zhí)行文件時,默認情況下啟用采樣分析器(但必要時可禁用)。請記住,為了獲得良好的配置文件,從而獲得良好的峰值性能,您需要運行相關的工作負載并正確地預熱應用程序。 我們還實現了一個上下文感知內聯器優(yōu)化,它使用新的采樣分析器將優(yōu)化工作更好地投入到熱代碼中。結果是2-7%更小的可執(zhí)行文件大小和增加的峰值性能。 我們改進了Native Image的循環(huán)向量化支持,允許編譯器向量化更多的循環(huán)以實現更快的執(zhí)行,并將某些代碼塊在 AOT 上的表現與 JIT 相媲美。
五、Native Image Bundles
表面上看,Native Image 構建命令(native-image -jar MyApp.jar)可能看起來很簡單,但它啟動了一個復雜的構建過程,有許多變量和屬性依賴于環(huán)境。如果能夠復制構建過程,例如用于更新和修復應用程序,或者重現問題,將非常有幫助。為此,這個版本引入了 Native Image Bundles。現在,您可以生成一個構建捆綁包,其中包含應用程序的 JAR 文件以及有關參數、環(huán)境變量、系統(tǒng)屬性設置、類路徑和模塊路徑選項的信息。要生成捆綁包,請在構建本地可執(zhí)行文件時使用 — bundle-create= 文件和 目錄。有了這些文件,您可以通過運行以下命令來復制構建過程:native-image -bundle-apply=…/path/to/捆綁包應該簡化更新 Native Image 部署,并有助于調試和重現問題。請嘗試使用這個功能,并讓我們知道您的想法!
六、Build 構建報告
Native Image 現在可以生成構建報告,幫助您更好地了解可執(zhí)行文件的內容。構建報告以 HTML 格式展現,并提供以下信息:
構建環(huán)境和使用資源的信息 包括可達類型、字段和方法在內的分析結果 代碼和堆區(qū)域的完整分解 軟件材料清單(SBOM)
構建報告摘要和代碼區(qū)域分解使用 -H:+BuildReport 開啟這個實驗性功能。
七、Linux 下的 AWT
我們已經在 Native Image 中改進了 AWT 支持:除了 Windows 之外,它現在還可以在 Linux 上工作!這意味著更多的 GUI Java 應用程序現在可以在 Native Image 上運行。我們期待著看到您的應用程序使用 Native Image 運行并收到您的反饋。改進的 AWT 對于 macOS 的支持也正在路上。
一個使用 GraalVM 構建的 Linux 原生可執(zhí)行 AWT 應用
八、Native Image 開發(fā)經驗
隨著每次發(fā)布,我們都會引入更新,使開發(fā)GraalVM,特別是 Native Image 的開發(fā)人員體驗更加順暢。本次發(fā)布中有幾個更改:
改進了 Native Image 構建過程的內存占用。現在,構建器考慮可用內存,以減少在同一臺機器上運行許多其他進程時的內存壓力。它在許多情況下消耗更少的內存,因此也不太可能由于內存不足而失敗。同時,我們增加了 Native Image 可以使用的最大內存量,這將有助于構建大型應用程序。 對于我們的 Windows 用戶來說,有一個好消息!Native Image 現在會自動設置 Windows 的構建環(huán)境 —— 您不再需要使用 x64 Native Tools 命令提示符。我們還改進了 Windows 的調試:調試信息現在包括有關 Java 類型的信息。 我們繼續(xù)擴展我們的JFR支持。現在,還支持以下事件: ExecutionSample、ObjectAllocationInNewTLAB和JavaMonitorInflate。我們努力使元數據組合安全,以便添加新元數據將永遠不會破壞構建。 內部錯誤變得更加用戶友好。在失敗的情況下,Native Image構建將不再只顯示堆棧跟蹤,而是提供錯誤報告和如何報告問題的說明。 現在可以通過 LLVM 后端在 RISC-V 上使用 GraalVM Native Image —— 在相關博客文章中閱讀更多信息。
九、新的 Native Image 監(jiān)控功能 ??
受社區(qū)的強烈要求,我們實現了 JMX 遠程管理功能。它可以通過 --enable-monitoring選項進行啟用,例如:--enable-monitoring=jmxclient,jmxserver。請注意,此功能仍處于實驗階段。
十、開始 Native Image ?
我們經常會聽到這樣一個問題:“我怎樣才能知道是否可以使用 X 庫與 Native Image 一起使用”。現在在 graalvm.org 上,您可以找到一份經過測試并可與 Native Image 完美配合的庫和框架列表。目前,該列表包含了150多個經過驗證可以與 Native Image 一起使用的庫和框架,包括 Micronaut、Spring、Quarkus、Helidon、H2、GraphQL、MariaDB、Netty、MySQL、Neo4j、PostgreSQL、Testcontainers、Thymeleaf 等等。我們很高興看到我們的生態(tài)環(huán)境積極采用 Native Image,并通過GraalVM-reachability-metadata 倉庫提供支持。這個倉庫也與 Native Build Tools 集成在一起,因此現在可以自動發(fā)現和拉取依賴項的 Native Image 配置文件。
十一、GraalVM JDK 和編譯器更新
GraalVM JIT 現在已經支持 ZGC!ZGC 是一個低延遲的垃圾收集器,面向需要低延遲或大堆大小的應用程序。(目前,在 Native Image 中不支持 ZGC。)要啟用它,請使用命令行選項 -XX:+UseZGC。我們預計這個更新對于大型應用程序或低延遲至關重要的情況將有所裨益,并期待您的反饋和性能報告。 我們還正在開源 Ideal Graph Visualizer(IGV)!?? IGV 是一款開發(fā)人員工具,可讓您分析編譯圖并調查性能問題。我們希望 IGV 對于那些在 GraalVM 之上實現語言或調查高級編譯問題的人特別有幫助。
十二、社區(qū)貢獻
graalvm-reachability-metadata 倉庫共收到近200個社區(qū)貢獻,使Java庫能夠在Native Image中使用。我們特別感謝 Spring 和 Micronaut 團隊的大力支持。 我們與 Red Hat 一起繼續(xù)構建 JFR 支持、改進 Windows 上的調試,并添加了實驗性的 JMX 支持。 您提供的所有反饋、性能基準和問題報告都有助于我們在每次發(fā)布時進一步改進 GraalVM。
十三、GraalVM 生態(tài)有什么新功能
我們基于社區(qū)調查的回答,發(fā)布了一份GraalVM生態(tài)系統(tǒng)的大概述:最常用的功能和工具、庫和框架的采用情況、編程語言等等:GraalVM 社區(qū) 2022 調查報告【譯】。 Spring Boot 發(fā)布了支持 Native Image 的主線版本 Spring Boot 3.0 !?? Quarkus發(fā)布了帶有許多新功能的 Quarkus 3;我最喜歡的可能是新的改進和可擴展 Dev UI —— 試試吧! Micronaut 將很快發(fā)布4.0版本,使用 Java 17 作為基線,并提供更快的構建方式 —— 您已經可以嘗試 Milestone 2 了。 現在您可以使用 Azure App Insights 監(jiān)控 GraalVM 和 Spring Boot 應用程序。 Testcontainers 通過 GraalVM Reachability 倉庫與 Native Image 一起工作,還有幾個框架提供平穩(wěn)的集成 —— 例如看看 Micronaut 如何在Native Image 和 JVM 模式下測試 RabbitMQ 集成。 Ionut Balosin 和 Florin Blanaru發(fā)布了一份獨立(非常詳細)的 GraalVM 與 OpenJDK C2 性能研究。 我們還看到了關于 Apache Kafka、Quarkus 和 GraalVM 的有趣實驗:單個代理節(jié)點運行需要約 130 毫秒,并且具有 60MB 的 RSS。
