利用OpenJ9大幅度降低JAVA內存佔用

OpenJ9

OpenJ9

介紹

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

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

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

好處

  • 內存佔用少
  • 啓動時間短
  • 吞吐量高
  • 更加適合微服務以及容器

性能

  • 啓動後佔比減少66%
    啓動後佔比減少66%
    OpenJ9針對雲工作負載進行了高度優化,在這些工作中,內存佔用小非常重要。即使啓用了其他優化,佔用空間仍保持不變。

  • 高負載期間的佔比減少了63%
    高負載期間的佔比減少了63%
    當施加負載時,內存佔用量迅速增加,但是在穩定狀態下,帶有OpenJ9的OpenJDK 8使用的物理內存比帶有HotSpot的OpenJDK 8少大約63%。

  • 啓動時間加快42%
    啓動時間加快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小時後內存佔用情況:
openjdk運行2小時後內存佔用情況
後續運行更久時甚至達到了90%以上。
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小時後內存佔用情況:
openj9運行2小時後內存佔用
後續運行更久也沒有明顯變化。
後續運行更久也沒有明顯變化

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章