1、JVM虛擬機組成及內存分配
三大部分:
- 類裝載子系統
- JVM虛擬機
- 字節碼執行引擎
其中,JVM虛擬機運行時數據區(內存模型)包含五部分:堆、棧(線程)、方法區(元空間)、本地方法棧、程序計數器。
- 堆:對象等,
- 棧:方法等,
- 方法區:常量、靜態變量、類信息
- 本地方法棧:native修飾的方法、接口,C++實現
- 程序計數器:記錄線程下一次該執行的位置
其中:
- 所有線程共享:堆、方法區
- 線程私有:棧、本地方法棧、程序計數器
字節碼執行引擎負責為程序計數器的下一個執行位置做更新。
字節碼執行引擎負責垃圾收集線程。
一個方法對應的幀棧中包括:
- 局部變量表
- 操作數棧
- 動態鏈接
- 方法出口
2、GC垃圾回收機制解析
定位到 GC Roots根節點——可達性分析算法
2.1 gc時內部邏輯:
- Eden space:伊甸園區,屬于年輕代區。gc時判斷存在引用則移動到survivor區。此處無引用,gc,屬于minor gc。
- Survivor:屬于年輕代,有survivor0、survivor1兩部分,一次gc引用判斷之后,如果還有引用,年齡+1,從0區移動到1區。
- Old Gen:老年代,存活時間很久的對象(有些判斷邏輯下根據一批對象的內存大小超過一定大小,比如60%直接從Eden移動到老年代)。survivor區中的年齡達到15時,移動到此,當此處內存已滿,無法繼續向此處移動時,內存溢出,OOM。需要full gc,即干掉這塊內存占用。
其中,Eden區與survivor區內存占比8:1。
常用jvm調優工具:
- jmap
- jstack
- Jinfo
- jvisualvm
- JConsole
- 近年國內熱門好用:阿里巴巴Arthas
2.2 調優工具:阿里巴巴Arthas詳解:
Arthas 是一款線上監控診斷產品,通過全局視角實時查看應用 load、內存、gc、線程的狀態信息,并能在不修改應用代碼的情況下,對業務問題進行診斷,包括查看方法調用的出入參、異常,監測方法執行耗時,類加載信息等,大大提升線上問題排查效率。官方文檔十分詳細,地址:https://arthas.aliyun.com/doc/
可以在線解決生產問題。無需 JVM 重啟,無需代碼更改。 Arthas 作為觀察者永遠不會暫停正在運行的線程。
Arthas(阿爾薩斯)能做什么?
幫助解決以下問題:
- 這個類從哪個jar包加載到?為什么會報各種類相關的Exception?
- 我改的代碼為什么沒有執行到?難道是沒commit?分支搞錯了?
- 遇到問題無法線上debug,難道只能通過加日志再重新發布?
- 線上遇到某個用戶的數據處理有問題,但線上無法debug,線上無法復現!
- 是否有一個全局視角來查看系統的運行狀況?
- 有什么辦法可以監控到JVM的實時運行狀態?
- 怎么快速定位到應用的熱點,生成火焰圖?
- 怎樣直接從JVM內查找某個類的實例?
版本:支持 JDK 6+(4.x 版本不再支持 JDK 6 和 JDK 7),支持 Linux/Mac/Windows,采用命令行交互模式,同時提供豐富的 Tab
自動補全功能,進一步方便進行問題的定位和診斷。
2.3 JVM調優的最終目的——減少STW
STW:stop the world,停頓影響。GC操作會暫停用戶線程,如果出現次數頻繁或者操作耗時,影響性能。所以JVM調優的目的是為了減少SWT的影響,從而卡頓減少、提升性能。
3.常用GC機制的特征
- G1:部分回收,STW時間設置后,在設置的時間內回收,然后繼續,避免堆內存比較大時GC的STW過久。
- Parallel:jdk8默認回收機制,一次性回收。