Alibaba Dragonwell 8 是一款免費的 OpenJDK 發行版。它提供長期支持,包括性能加強和安全修復。Alibaba Dragonwell 8 目前支持 X86-64/Linux 平臺,在數據中心大規模 Java 應用部署狀況下, 能夠大幅度提升穩定性、效率以及性能。Alibaba Dragonwell 8 是 OpenJDK 的下游(friendly fork),使用了和 OpenJDK 同樣的 licensing。Alibaba Dragonwell 8 與 Java SE 標準兼容,用戶可使用 Alibaba Dragonwell 8 開發和運行 Java 應用程序。這次開源的 Alibaba Dragonwell 8 是阿里巴巴內部 OpenJDK 定製版 AJDK 的開源版本, AJDK 爲在線電商,金融,物流作告終合業務場景的優化,運行在超大規模的,100,000+ 服務器的阿里巴巴數據中心。java
目前 Alibaba Dragonwell 8 只支持 Linux x86-64 平臺,而且提供了二進制的預編譯 JDK 包,您能夠經過下面的簡單兩步安裝 Alibaba Dragonwell 8。git
安裝完畢後,只須要將應用引用 的 JAVA_HOME 指向 Alibaba Dragonwell 8 的安裝目錄就可使用了。咱們以Tomcat8.5.39 版本爲例,爲了讓 Tomcat 運行在 Alibaba Dragonwell 8上面,只須要在啓動Tomcat時使用以下命令:github
JAVA_HOME=/path/to/dragonwell8/installation sh tomcat/bin/catalina.sh start複製代碼
爲了確認是運行在 Alibaba Dragonwell 8上面,能夠進一步經過給 java 命令添加 -showversion
參數來打印 JDK 版本信息加以判斷。web
JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-showversion" sh tomcat/bin/catalina.sh start複製代碼
啓動完畢後在 tomcat/logs/catalina.out 文件的開頭,能夠看到 Alibaba Dragonwell 8 的版本信息
算法
在 8.0-preview 這個版本中, Alibaba Dragonwell 8 提供了兩個在阿里巴巴的生產環境中進行過普遍驗證的特性:JWarmUp 和 Java Flight Recorder。這兩個特性都已經在上游 OpenJDK 社區提交了 JEP 或 patch,在上游合併完成以前,咱們但願讓 Alibaba Dragonwell 8 的用戶能夠提早使用到這兩個特性。apache
OpenJDK 使用了 JIT(Just-in-time) 即時編譯技術,能夠動態的把 Java 字節碼編譯成高度優化過機器碼,提升執行效率,但在編譯以前,Java 代碼是以相對低效的解釋器模式執行的。bootstrap
在應用啓動完成後、業務流量剛進來的短期內,容易出現的情況是大量 Java 方法開始被 JIT 編譯,同時業務請求被較慢的解釋器模式執行,最終的結果就是系統負載飆高,可能致使不少用戶請求超時。爲了解決這個問題,以前的不少作法是使用模擬流量來提早預熱應用,JWarmUp 特性提供了一個新的選擇,就是利用 Java 虛擬機前一次執行編譯得記錄來預熱本次應用的執行。數組
JWarmUp 的原理以下圖所示:
tomcat
一個典型的應用場景是當應用須要發佈新版本的時候,安全
這樣當用戶請求進入的時候,應用就會處於性能最高的峯值狀態。
還以 Tomcat 應用爲例,能夠添加下面的命令行參數來在 beta 環境中收集 JIT 編譯時生成的元數據,其中參數 -XX:CompilationWarmUpLogfile=
指定的就是生成的 JWarmUp 文件的路徑。
JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:ReservedCodeCacheSize=512m -XX:CompilationWarmUpLogfile=$PWD/jwarmup.log -XX:+CompilationWarmUpRecording -XX:+CompilationWarmUp -XX:-TieredCompilation -XX:+DeoptimizeBeforeWarmUp -XX:CompilationWarmUpDeoptTime=30 -XX:+PrintCompilationWarmUpDetail" sh bin/catalina.sh start複製代碼
生成以後能夠把這個文件經過 OSS、SFTP 等方式傳輸到生產環境的機器上。
在生產環境的機器上,只須要使用下面的參數,就能夠利用以前的預熱數據來啓動一個新的 Tomcat 實例,其中參數 -XX:CompilationWarmUpLogfile=
制定的就是須要被加載的 JWarmUp 文件路徑,這個文件應該是上一步收集預熱數據時從 beta 環境複製過來的。
JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:ReservedCodeCacheSize=512m -XX:CompilationWarmUpLogfile=$PWD/jwarmup.log -XX:+CompilationWarmUp -XX:-TieredCompilation -XX:+DeoptimizeBeforeWarmUp -XX:CompilationWarmUpDeoptTime=30 -XX:+PrintCompilationWarmUpDetail" sh bin/catalina.sh start複製代碼
JFR(Java Flight Recorder)是 JVM 內置的基於事件的性能分析特性,這是 Oracle JDK7u4 版本開始提供的商業特性,2018 年的時候在 JDK11 上開源了這個特性,可是一直沒有針對 JDK8 版本的支持。
阿里巴巴和 RedHat、Azul、Amazon 等公司一塊兒合做嘗試把這個特性移植回 JDK8上,不過該 patch 暫時尚未合併回 OpenJDK8u倉庫,咱們在 Alibaba Dragonwell 8 中提供了 Alibaba 移植的 JFR 版本,用於幫助用戶提早獲取這方面的支持。
JFR 的用法很簡單,用戶使用命令行參數或者 jcmd 命令控制 HotSpot 輸出性能數據到文件中,而後就能使用開源的 jmc 工具在圖形界面中打開、分析生成的數據文件了。
在 Alibaba Dragonwell 8中,默認狀況下 JFR 特性是處於關閉的狀態,必須添加命令行參數 -XX:+EnableJFR
來容許使用 JFR 特性。 Alibaba Dragonwell 8 提供了不一樣的方式來使用 JFR 採集性能數據。
應用能夠能夠經過命令行參數指定 JFR 再啓動後立馬開始採集數據,這個對於診斷啓動階段的問題會頗有幫助。下面的示例命令會在 Java 進程的 JFR 模塊初始化後就開始收集 JFR 數據,持續一分鐘,而且把數據都輸出到名爲rec.jfr 的文件中。
JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:+EnableJFR -XX:StartFlightRecording=duration=1m,filename=rec.jfr" sh bin/catalina.sh start複製代碼
應用也能夠只添加 -XX:+EnableJFR
,而後經過 jcmd
命令在應用啓動後的任意時間點開始採集數據,這種狀況更加靈活可控,能夠知足隨時隨地進行分析的需求。
以 Tomcat 爲例,啓動 Tomcat 的命令能夠是:
JAVA_HOME=/path/to/dragonwell8/installation JAVA_OPTS="-XX:+EnableJFR" sh bin/catalina.sh start複製代碼
當須要收集數據進行分析時,只須要使用目標 Tomcat 進程的 PID 來執行 JFR 對應的 jcmd 命令便可。以 Tomcat 爲例,若是須要在指定時刻開始收集 10 秒的數據,那麼觸發的命令以下:
$ ps ax | grep tomcat
77522 pts/18 Sl+ 0:08 /home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/../j2sdk-image/bin/java -Djava.util.logging.config.file=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -XX:+EnableJFR -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/bin/bootstrap.jar:/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/bin/tomcat-juli.jar -Dcatalina.base=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39 -Dcatalina.home=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39 -Djava.io.tmpdir=/home/chuansheng.lcs/dw_test/apache-tomcat-8.5.39/temp org.apache.catalina.startup.Bootstrap start
98451 pts/22 S+ 0:00 grep --color=auto tomcat
$ dragonwell8_home/bin/jcmd 77522 JFR.start duration=10s filename=$PWD/rec3.jfr
77522:
Started recording 3. The result will be written to:
/home/my/workdir/rec3.jfr複製代碼
10 秒以後能夠看到生成了 JFR 數據文件/home/my/workdir/rec3.jfr,使用 JMC 便可進行分析。
也能夠不指定收集數據的時間,直接啓動 JFR 收集,而且在須要的時候手動把全部生成的數據一次性 dump 到文件,
$ dragonwell8_home/bin/jcmd 2823 JFR.start filename=$PWD/rec4.jfr
2823:
Started recording 4. No limit specified, using maxsize=250MB as default.
Use JFR.dump name=4 to copy recording data to file.
$ dragonwell8_home/bin/jcmd 2823 JFR.dump name=4 filename=rec4.jfr
2823:
Dumped recording "Recording-4", 332.7 kB written to:
/path/to/my/workdir/rec4.jfr複製代碼
JFR 記錄 Java 應用性能數據的輸出是一個二進制的文件,咱們藉助於 JMC(Java Mission Control) 工具能夠在圖形化界面裏面分析具體的性能數據。這個工具是開源產品,沒有包括在 Alibaba Dragonwell 8裏面,須要到 OpenJDK 的官方網站下載使用,jdk.java.net/jmc/。
請注意, Alibaba Dragonwell8 生成的JFR數據文件須要 7.0 或更高版本的 JMC 工具來分析。
打開 JMC 後,能夠點擊左側的詳細類別來詳細分析採樣時間段內發生的各類事件。
Alibaba Dragonwell 8 還內置一些方便的診斷特性,主要包括
能夠經過新的 JVM 參數"-XX:ArrayAllocationWarningSize=",好比下面代碼中分配了比較大的數組
public static void main(String[] args) {
doAlloc(32 * 1024 * 1024 + 1);
}
private static Object doAlloc(int size) {
return new byte[size];
}複製代碼
執行時若是添加 ArrayAllocationWarningSize 選項就會打印出分配該數組時的 Java 堆棧
Alibaba Dragonwell 8 默認使用了 CMS (Concurrent Mark Sweep) 算法,新生代使用了 ParNew 算法,因此內置兩個針對 ParNew GC 日誌的加強
jinfo -flag +PrintYoungGenHistoAfterParNewGC <pid>複製代碼
打印完成後,這個選項會被重置回 false 狀態,防止過多的輸出,一個典型的輸出例子以下:
Alibaba Dragonwell 8 的 jmap 工具支持一個新的 dump 選項「mini」能夠在作 heapdump 的時候跳過全部的原始類型數組的內容,從而大大減少生成的 heapdump 文件大小,這對於只須要排查類型、對象關係的場景會比較有幫助。
示例命令以下:
本文爲雲棲社區原創內容,未經容許不得轉載。