文章目錄
- 1 JVM記憶體模型
- 2 調優診斷工具
-
- 2.1 jvisualvm
- 2.2 阿裡arthas
-
- 2.2.1 直接下載下傳jar包運作
- 2.2.2 常用指令
- 3 垃圾回收過程
-
- 3.1 垃圾回收機制
- 3.2 回收過程
-
- 3.2.1 minor gc:當Eden區放滿,回收新生代空間
- 3.2.2 新生代轉移到老年代
-
- 3.2.2.1 長期存活的對象
- 3.2.2.2 Survivor區域存滿,會把這些對象拷貝老年代
- 3.2.2.3 大對象進入老年代
- 3.2.2.4 對象動态年齡判斷
- 3.2.3 full gc:回收整個堆空間
- 4 調優目的:減少full gc的頻率-STW(Stop The World)
-
- 4.1 為什麼要設計STW?
1 JVM記憶體模型
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYTMfhHLlN3XnxCM38FdsYkRGZkRG9lcvx2bjxCMy8VZ6l2cs0TTU9UNFpmYxgGWhFDatVWQClGVF5UMR9Fd4VGdsATNfd3bkFGazxycykFaKdkYzZUbapXNXlleSdVY2pESa9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL5YmY1I2NmFzYmJGOhFmM4UGZ1QDOllTNiNWOmVTNhF2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
2 調優診斷工具
2.1 jvisualvm
2.2 阿裡arthas
2.2.1 直接下載下傳jar包運作
java -jar arthas-boot.jar
2.2.2 常用指令
1、dashboard 顯示所有線程的執行情況
可以看到上述程式執行的堆記憶體情況(Eden區、Survivor區,old區,元空間,gc等)
2、thread [threadId] 顯示某個thread的詳細情況
3、thread -b 顯示阻塞情況
4、反編譯:jad com.hd.Test
反編譯可以幫助開發人員确定代碼是否成功釋出
3 垃圾回收過程
3.1 垃圾回收機制
可達性分析。從GC ROOT(棧裡的局部變量,方法區的靜态變量,常量)找到可達的對象,标記這些對象是非垃圾。
3.2 回收過程
3.2.1 minor gc:當Eden區放滿,回收新生代空間
- 通過可達性分析标記Eden區域和S0區域的垃圾
- 執行gc回收
- 将Eden和S0的非垃圾對象複制到S1區,将他們的年齡+1.
- 結束回收。後續回收的空間是Eden和S1。
3.2.2 新生代轉移到老年代
3.2.2.1 長期存活的對象
預設15歲,CMS預設6歲。通過參數
XX:MaxTenuringThreshold
設定。
3.2.2.2 Survivor區域存滿,會把這些對象拷貝老年代
3.2.2.3 大對象進入老年代
大對象就是需要大量連續存儲空間的對象(比如字元串、數組等)。
JVM參數
-XX:PretenureSizeThreshold
可以設定大對象的大小。如果超過這個值則對象直接進入老年代。該參數隻在
Serial
和
ParNew
兩個收集器下有效。
好處:避免大對象配置設定記憶體時的複制操作而降低效率
3.2.2.4 對象動态年齡判斷
年齡1+年齡2+年齡3+年齡N的對象加起來的空間,大于survivor區域的一半(具體的比例通過參數
-XX:TargetSurvivorRatio
設定),就會讓年齡N和年齡N以上的對象進入老年代。動态年齡判斷應該是這樣子的。說的通俗一點:就是年齡從小到大對象的占據空間的累加和,而不是某一個特定年齡對象占據的空間。
案例:億級網站搶購活動分析
3.2.3 full gc:回收整個堆空間
1、當老年代存滿時,會觸發full gc
2、調用System.gc()方法
4 調優目的:減少full gc的頻率-STW(Stop The World)
minor gc和full gc都會導緻STW,導緻應用程式暫停。
如果gc時間比較長,則STW時間也會很長,就會造成程式響應很慢。
4.1 為什麼要設計STW?
如果不STW有什麼壞處?【對象狀态在使用者線程執行過程中不斷變化,造成錯标記或漏标記】
- gc過程中,使用者線程還在進行,可能會出現gc到一半的時候,已經判斷為非垃圾的對象變成了垃圾(漏标記)。
- gc已經被标記為垃圾的對象,使用者線程後續繼續使用了(錯标記)。