探探Java之 JVM GC與調優
調優前的基礎概念
- 吞吐量:使用者程式碼時間 /(使用者程式碼執行時間 + 垃圾回收時間)
- 響應時間:STW越短,響應時間越好
- 所謂調優,首先確定,追求啥?吞吐量優先,還是響應時間優先?還是在滿足一定的響應時間的情況下,要求達到多大的吞吐量。如科學計算、資料探勘:吞吐量優先;網站、GU、 API 等追求響應時間。
什麼是調優
- 根據需求進行JVM規劃和預調優
- 優化JVM執行環境(慢、卡頓)
- 解決JVM執行過程中出現的各種問題(如OOM)
-
根據需求進行JVM規劃和預調優
調優一般來說,從業務場景開始,沒有業務場景的調優都是耍流氓;無監控 (壓力測試,能看到結果),不調優。
步驟
- 熟悉業務場景
- 選擇回收器組合,沒有最好的GC,只有最適合的GC。追求響應時間或停頓時間選擇CMS、G1、ZGC追求吞吐量 可選擇PS。
- 計算記憶體需求(經驗值 1.5G -16G)
- 選定CPU(越高越好)
- 設定年代大小,升級年代
- 設定日誌引數,日誌檔案全放一個?10T日誌怎麼查。可以設定滾動日誌如
-Xloggc:/opt/xxx/logs/xxx-xxx-gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCCause
, 或是每天產生一個日誌檔案。 - 觀察日誌情況
提供一個簡單的案例分析
案例1:垂直電商,最高每日百萬訂單,處理訂單系統需要什麼樣的伺服器配置?
這個問題比較業餘,因為很多不同的伺服器配置都能支撐(1.5G -16G)。可以具體分析:一天中特定的高峰期1小時有360000訂單集, 1000個訂單/秒,可以根據經驗值估算需要的記憶體配置。如果非要要計算,可以這麼算:一個訂單產生需要多少記憶體?512K * 1000,需要500M記憶體。
從另外專業的角度考慮:要求響應時間100ms,這種情況下可以通過壓測的方式找到符合的伺服器配置。
-
優化JVM執行環境(慢、卡頓)
-
提供一個簡單的案例分析。
有一個50萬PV的資料類網站(從磁碟提取文件到記憶體)原伺服器32位,1.5G的堆.使用者反饋網站比較緩慢,因此公司決定升級。新的伺服器為64位,16G的堆記憶體,結果使用者反饋卡頓十分嚴重,反而比以前效率更低了。
- 為什麼原網站慢?很多使用者瀏覽資料,很多資料load到記憶體,記憶體不足,頻繁GC,STW長,響應時間變慢。
- 為什麼會更卡頓?記憶體越大,FGC時間越長
- 如何解決?可以換垃圾回收器,如從PS 換為PN + CMS 或者是1.8以上的直接用G1。
-
系統CPU經常100%,如何調優?(面試高頻)
CPU100%那麼一定有執行緒在佔用系統資源,
- 找出哪個程式cpu高(top)
- 該程式中的哪個執行緒cpu高(top -Hp)
- 匯出該執行緒的堆疊 (jstack)
- 查詢哪個方法(棧幀)消耗時間長 (jstack)
- 對比工作執行緒佔比高還是垃圾回收執行緒佔比高
-
系統記憶體飆高,如何調優(面試高頻)
思路: 匯出堆記憶體(jmap); 使用工具如(jhat jvisualvm mat jprofiler)分析
-
-
解決JVM執行過程中出現的各種問題
提供一個測試案例來說明分析過程和常用的工具,程式碼如下:
/** * 從資料庫中讀取信用資料,套用模型,並把結果進行記錄和傳輸 */ public class T15_FullGC_Problem01 { private static class CardInfo { BigDecimal price = new BigDecimal(0.0); String name = "張三"; int age = 5; Date birthdate = new Date(); public void m() {} } private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50, new ThreadPoolExecutor.DiscardOldestPolicy()); public static void main(String[] args) throws Exception { executor.setMaximumPoolSize(50); for (;;){ modelFit(); Thread.sleep(100); } } private static void modelFit(){ List<CardInfo> taskList = getAllCardInfo(); taskList.forEach(info -> { // do something executor.scheduleWithFixedDelay(() -> { //do sth with info info.m(); }, 2, 3, TimeUnit.SECONDS); }); } private static List<CardInfo> getAllCardInfo(){ List<CardInfo> taskList = new ArrayList<>(); for (int i = 0; i < 100; i++) { CardInfo ci = new CardInfo(); taskList.add(ci); } return taskList; } }
-
啟動命令
java -Xms20M -Xmx20M -XX:+UseParallelGC -XX:+HeapDumpOnOutOfMemoryError T15_FullGC_Problem01
-
一般是運維團隊首先受到報警資訊(CPU、Memory)
-
top命令觀察到問題:記憶體不斷增長,CPU佔用率居高不下
-
top -Hp 觀察程式中的執行緒,哪個執行緒CPU和記憶體佔比高
-
jps定位具體java程式;jstack pid 定位執行緒狀況,重點關注:WAITING BLOCKED
waiting on <0x0000000088ca3310> (a java.lang.Object)
假如有一個程式中100個執行緒,很多執行緒都在waiting on ,一定要找到是哪個執行緒持有這把鎖。 怎麼找?搜尋jstack dump的資訊,找 ,看哪個執行緒持有這把鎖處於RUNNABLE狀態。 -
jinfo pid 檢視JVM的情況,一般用處不大。
-
通過jstat -gc 動態觀察gc情況;或是閱讀GC日誌發現頻繁GC;或是通過arthas觀察gc情況。
-
線上定位,查詢有多少物件產生,注意大量的物件,使用
jmap -histo pid |head -20
-
jmap -dump:format=b,file=xxx pid
可以線上堆轉儲,但是要慎重影響很大。線上系統記憶體特別大,jmap執行期間對程式產生很大影響,甚至卡頓(電商不適合)。
如何解決? 啟動時候設定引數HeapDumpOnOutOfMemoryError,OOM的 時候會自動產生堆轉儲檔案;如果線上很多伺服器備份(高可用),停掉這臺伺服器對其它服務沒影響也可以線上堆轉儲;線上定位也可以用阿里的arthas。
-
使用MAT/jhat/jvisualvm 進行dump檔案分析。
建議使用MAT/jvisualvm 裝入分析,介面友好且支援複雜查詢
-
最難的一點:定位到程式碼中的問題
示例程式碼的問題是:執行緒池使用不當引起OOM;不停new CardInfo物件不停地起定時執行緒去處理,導致這些物件越來越多
-
相關文章
- JVM調優——JVM監控工具jvisualvm的使用及GC外掛安裝JVMLVMGC
- JVM之GC趣解JVMGC
- JVM面試問題系列:JVM 配置常用引數和常用 GC 調優策略JVM面試GC
- 【深入理解JVM】8、JVM實戰調優+GC演算法+JVM調優如何定位問題+常見的定位JVM優化命令【面試必備】JVMGC演算法優化面試
- JVM 系列文章之 Full GC 和 Minor GCJVMGC
- 《java學習三》jvm效能優化-------調優JavaJVM優化
- 【JAVA進階架構師指南】之五:JVM效能調優Java架構JVM
- JVM調優JVM
- JVM效能調優與實戰篇JVM
- GC調優記錄(一)GC
- JVM調優之JConsole和JVisualVM工具使用JVMLVM
- JVM調優策略JVM
- JVM之調優及常見場景分析JVM
- Java 效能調優:最佳化 GC 執行緒設定JavaGC執行緒
- JVM調優淺談JVM
- JVM調優推薦JVM
- 掌握JVM調優命令JVM
- JVM GC 與 記憶體分配策略JVMGC記憶體
- 瞭解Java物件,簡單聊聊JVM調優分析Java物件JVM
- JVM調優筆記(一)--Nacos GC引發的服務批次下線問題JVM筆記GC
- JVM效能調優與實戰進階篇-上JVM
- JVM調優:HotSpot JVM垃圾收集器JVMHotSpot
- Java面試題中高階進階(JVM調優篇)Java面試題JVM
- JVM調優-學習篇JVM
- "簡單"的jvm調優JVM
- JVM 調優示例和配置JVM
- JVM 調優命令&工具使用JVM
- JVM 引數調優(qbit)JVM
- “簡單”的jvm調優JVM
- JVM常用調優引數JVM
- JVM 調優(學習篇)JVM
- java學習筆記-4 JVM垃圾回收(GC)Java筆記JVMGC
- JVM 系列文章之 GC 演算法淺析JVMGC演算法
- “阿里架構師”的JVM之GC詳解阿里架構JVMGC
- 【JVM進階之路】十:JVM調優總結JVM
- 淺談JVM整體架構與調優引數JVM架構
- JVM快速調優手冊v1.0之六:JVM引數設定、分析JVM
- [仁潤雲技術團隊]JVM之GC與記憶體分配策略JVMGC記憶體