1. 程式人生 > 實用技巧 >利用OpenJ9大幅度降低JAVA記憶體佔用

利用OpenJ9大幅度降低JAVA記憶體佔用

OpenJ9

介紹

  • OpenJ9是一種高效能,可擴充套件的Java™虛擬機器(VM)實現,完全符合Java虛擬機器規範。

  • 在執行時,VM解釋由Java編譯器編譯的Java位元組碼。VM充當語言與底層作業系統和硬體之間的翻譯器。Java程式需要特定的VM才能在特定的平臺(例如Linux®,z /OS®或Windows™)上執行。

  • OpenJ9 VM會自動檢測它何時在docker容器中執行,並使用一種機制來檢測VM何時處於空閒狀態。當檢測到空閒狀態時,OpenJ9會執行垃圾回收週期,並將可用記憶體頁釋放回作業系統。還壓縮物件堆,以充分利用可用記憶體來進行進一步的應用程式處理。對於基於記憶體使用量收費的雲服務,保持較小的佔用空間可以節省成本。

好處

  • 記憶體佔用少
  • 啟動時間短
  • 吞吐量高
  • 更加適合微服務以及容器

效能

  • 啟動後佔比減少66%

    OpenJ9針對雲工作負載進行了高度優化,在這些工作中,記憶體佔用小非常重要。即使啟用了其他優化,佔用空間仍保持不變。

  • 高負載期間的佔比減少了63%

    當施加負載時,記憶體佔用量迅速增加,但是在穩定狀態下,帶有OpenJ9的OpenJDK 8使用的實體記憶體比帶有HotSpot的OpenJDK 8少大約63%。

  • 啟動時間加快42%

    共享類和預編譯(AOT)技術通常會減少啟動時間。通過同時使用-Xquickstart模式,可以將啟動時間最多減少42%。

  • 達到同樣的吞吐量

    儘管帶有OpenJ9的OpenJDK 8和帶有Hotspot的OpenJDK 8都達到了相似的峰值吞吐量,但是帶有OpenJ9的OpenJDK 8達到了約1分鐘的峰值。

  • 在容器中的滿載加速度

    OpenJ9在8.5分鐘內達到單個CPU核心的峰值吞吐量,而Hotspot則為30分鐘。對於在資源受限的環境(例如容器​​)中執行的短期VM而言,更快地執行更多工作非常重要。

這些結果表明,OpenJ9在(通常是相互衝突的)效能指標之間達到了良好的平衡:藉助AOT技術,它可以節省大量的空間並縮短啟動時間,同時還提供與Hotspot競爭的吞吐量效能。 由於其記憶體佔用量低,OpenJ9特別適合於雲端計算環境,在這種環境中,節省記憶體可為雲使用者和提供商節省成本。

實際使用

目前我的專案是一個基於 Spring Boot 開發的,專案中加入了大量定時器以及多執行緒,網路IO請求,資料計算等。生產環境部署方式採用的Docker

,之前是採用的官方的openjdk映象,目前已經改為了openj9,至於為什麼請看以下資料。

我這裡以比較突出的記憶體佔用進行比較。

伺服器配置

2核4G

openjdk

對應的Dockerfile

FROM openjdk:8-jdk-alpine
ADD target/app.jar app.jar
ENTRYPOINT [ \
    "java", \
    "-XX:MetaspaceSize=256m", \
    "-XX:MaxMetaspaceSize=256m", \
    "-Xms2048m", \
    "-Xmx2048m", \
    "-Xmn256m", \
    "-Xss256k", \
    "-XX:SurvivorRatio=8", \
    "-XX:+UseConcMarkSweepGC", \
    "-Duser.timezone=GMT+08", \
    "-Djava.security.egd=file:/dev/./urandom", \
    "-jar", \
    "/app.jar", \
    "--spring.profiles.active=prod" \
]

執行2小時後記憶體佔用情況:

後續執行更久時甚至達到了90%以上。

openj9

對應的Dockerfile

FROM adoptopenjdk:8-jdk-openj9
ADD target/app.jar app.jar
ENTRYPOINT [ \
    "java", \
    "-XX:MetaspaceSize=256m", \
    "-XX:MaxMetaspaceSize=256m", \
    "-Xms2048m", \
    "-Xmx2048m", \
    "-Xmn256m", \
    "-Xss256k", \
    "-XX:SurvivorRatio=8", \
    "-XX:+UseConcMarkSweepGC", \
    "-Duser.timezone=GMT+08", \
    "-Djava.security.egd=file:/dev/./urandom", \
    "-Xshareclasses", \
    "-Xquickstart", \
    "-jar", \
    "/app.jar", \
    "--spring.profiles.active=prod" \
]

執行2小時後記憶體佔用情況:

後續執行更久也沒有明顯變化。

最後從資料看來結果,記憶體佔用真的低,非常節省伺服器資源,相同負載下至少節省一半的伺服器資源。
值得推薦大家去嘗試。