如何快速、低成本、低擾動地執行一段Java程式碼

lcc發表於2021-09-09

JVM是個執行服務端應用的好VM,但如果你只是想頻繁地執行一段Java寫的指令碼,或者在跑一些輔助性的Java程式比如監控,比如日誌收集,這時候的訴求就和平日裡的應用不一樣了:


1.啟動快速,動靜小。

2.低成本,節約CPU、記憶體和執行緒。

3.低擾動,不干擾主應用的執行。


圖片描述

一、從失敗的取經開始

第一時間,看看jmap,jstack們用了什麼引數,結果發現通通只有一個-Xms8m (在它們執行時,跑jps -v 可見,原始碼級確認JDK7見Makefile.launcher,JDK8見CompileLaunchers.gmk)。


另外,傳說中的-client,在多核的Linux伺服器上的也是無效的。


下面開始自己的折騰,首先給跑的指令碼配上"-Xloggc:gc.log

-XX:+PrintGCDetails -XX:+PrintGCDateStamps

-XX:+PrintGCApplicationStoppedTime", 在gc.log 裡就會有實際啟動引數,GC日誌,以及結束時列印記憶體各代的佔用。


其次,長期跑一個 pidstat -l 1| grep XXX 監控程式的CPU消耗


最後,jstack一下程式,看看裡面跑著多少執行緒,一個預設的JVM,執行緒數多得嚇人。


二、類的載入和編譯

1 -Xverify:none

來自最佳化Eclipse啟動速度的經驗,說關閉Java類載入驗證可以加快10% -15%的啟動速度。


2 設定編譯級別

JIT編譯之後的程式碼比解釋執行位元組碼更快,更省CPU,但編譯本身就需要CPU,也需要額外的編譯執行緒。臨時給啟動指令碼配上 “-XX:+PrintCompilation”,觀察編譯情況。


如果指令碼的程式碼只簡單的跑一次,比如vjtools裡的vjmxcli,建議就不要進行JIT編譯了,編譯完了也用不上,直接解釋執行就好。禁止它:-Djava.compiler=NONE


如果指令碼會用於迴圈計算,比如vjtools裡的vjmap,則建議開啟多層編譯,一開始就對執行到的方法進行靜態編譯,不用等方法被呼叫1萬次。多層編譯在JDK8預設開啟,顯式開啟:-XX:+TieredCompilation。


但開啟多層編譯也會導致程式執行初期有較多的編譯任務,吃比較多的CPU,可以顯式關掉多層編譯 -XX:-TieredCompilation來對比一下,綜合其帶來的效能提升,指令碼的生命週期長短,以及額外的CPU支出來綜合評價。


3 編譯執行緒的設定

在24核伺服器上,預設有4條C1編譯執行緒,8條C2編譯執行緒(多層編譯下),考慮到低成本原則,建議把它設到最小的-XX:CICompilerCount=2。


4 未來黑科技-AOT

JIT不夠酷,預先把程式碼編譯(Ahead-of-Time,AOT) 更好。 JDK9裡有一個Hotspot編譯器組搞的試驗性的jaotc,另一個選擇是GraalVM全家桶裡帶的 SubstrateVM ,這個支援JDK8。兩者都是基於Graal,看各位大大炫,但我還沒玩過。


三、GC 設定

這些指令碼,輔助程式一般不介意GC延時,建議使用吞度量最的序列收集演算法 -XX:+UseSerialGC,大大減少了其他GC演算法所產生的大量GC執行緒,保證自己GC時也不會影響到主應用。


如果依然想使用並行演算法,就一定要設定GC執行緒數,如果按預設值,在24核機器上YGC和CMS GC的執行緒數分別是18和5,一旦發生GC,將佔用大量的CPU核,直接對主應用產生巨大的影響。可設為-XX  arallelGCThreads=2 -XX:ConcGCThreads=1


四、記憶體設定

JVM的堆記憶體擴張並沒有想象中那麼智慧,當-Xms 與 -Xmx 不等,又沒有指定新生代比例時,新生代大小更是混亂。建議根據執行後的實際佔用及GC日誌,完整設定一個最合適的值。


快速執行一次的指令碼,老生代幾乎沒用,新生代可以設大些。


-Xms96m -Xmx96m -Xmn64m


長期執行的,則一般設為1:1。


-Xms256m -Xmx256m -XX:NewRatio=1


每條執行緒的記憶體從預設1M回到256k:-xss256k


永久代也可以一設,可惜JDK7/8的引數不相容,用java -version 拿版本號太貴了,所以如果明確了JDK版本的話可以設定,否則就算了。




作者:Java網際網路架構師
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2331/viewspace-2817531/,如需轉載,請註明出處,否則將追究法律責任。

相關文章