Java Leyden可3倍提高JVM啟動和預熱時間

banq發表於2024-05-24


Leyden 儲存庫的目的是對 Java 程式的啟動時間、達到峰值效能的時間和佔用空間進行原型改進 。

Leyden 原型包含許多最佳化,將工作從執行時轉移到早期階段,這些階段稱為訓練執行。在訓練執行中,我們根據對應用程式實際行為的觀察,預先計算各種資訊,並將位元組碼預編譯為本機程式碼。

Leyden repo 密切跟蹤 JDK 主線開發。我們通常只比主線JDK repo晚幾周。我們在 JDK 主線上實現了以下改進:

  • 統一快取資料儲存(JDK-8320264) :這是對CDS 的增強:
    • 除了類後設資料和堆物件之外,現在 CDS 還可以用於儲存分析資料以及已編譯的 Java 方法。
    • 我們簡化了 CDS 檔案的建立,以便您可以輕鬆地在 Java 應用程式中使用 CDS。
    • 該功能可透過新的 VM 標誌訪問-XX:CacheDataStore。
  • CDS 檔案中的已載入類 (JDK-8315737):這使 JVM 能夠在應用程式啟動時立即將類置於已載入狀態。因此,我們可以用相當簡化的假設來實現許多其他時間移位最佳化。
    • 可以使用新的 VM 標誌來訪問此功能-XX:+PreloadSharedClasses。(注意,當 JDK-8315737 整合到 JDK 主線時,此標誌將被重新命名)。
  • CDS 檔案中的方法配置檔案 (JDK-8325147):我們將訓練執行中的方法配置檔案儲存在 CDS 檔案中,從而使 JIT 能夠在預熱期間更早開始編譯。因此,Java 應用程式可以更快地達到最佳效能。
    • 該功能由新的 VM 標誌-XX:+RecordTraining和啟用-XX:+ReplayTraining。
  • 提前解析常量池條目:新的 VM 標誌-XX:+ArchiveFieldReferences, -XX:+ArchiveMethodReferences使得-XX:+ArchiveInvokeDynamic在訓練執行期間解析許多常量池條目成為可能。這允許應用程式更快地啟動。此外,已解析的常量池條目的存在允許 AOT 編譯器生成更好的程式碼。
  • Java 方法的提前編譯:訓練執行期間經常使用的方法可以編譯並與 CDS 檔案一起儲存。因此,只要應用程式在生產執行中啟動,其方法就可以在本地執行。
    • -XX:+StoreCachedCode此功能由新的 VM 標誌、-XX:+LoadCachedCode和啟用-XX:CachedCodeFile。
    • 目前,本機程式碼儲存在單獨的檔案中,但我們的計劃最終將本機程式碼儲存在 CDS 存檔檔案中。
  • 提前生成動態代理:動態代理經常被流行的應用程式框架使用。我們可以透過提前生成這些代理來縮短啟動時間。
    • 該功能由新的 VM 標誌啟用-XX:+ArchiveDynamicProxies。
  • 提前生成反射資料:反射資料(例如 的例項 java.lang.reflect.Method)由 JVM 生成以支援java.lang.reflect操作。我們可以提前生成這些資料以改善啟動。
    • 該功能由新的 VM 標誌啟用-XX:+ArchiveReflectionData。
  • 類載入器查詢快取:有時應用程式框架可能會按名稱執行多次類查詢(使用Class.forName()等)。此最佳化允許快速完成此類查詢,而無需掃描類路徑。
    • 該功能由新的 VM 標誌啟用-XX:+ArchiveLoaderLookupCache。

相關文章