JVM 運行時數據區深度解析:基於《深入理解 Java 虛擬機》學習筆記
JVM 在執行 Java 程序時,將管理的內存劃分為若干數據區域。按**線程隔離性**分類:
一、線程私有區域(隨線程生滅)
| 區域 | 核心作用 | 關鍵特徵 | 異常 |
| 程序計數器 (PC Register) | 記錄當前線程執行的字節碼行號(指令地址) | 唯一不會 OOM 的區域;執行 Native 方法時為空 | — |
| 虛擬機棧 (VM Stack) | Java 方法執行內存模型:局部變量表、操作數棧、動態連接、返回地址 | 棧幀隨方法調用入棧/出棧;深度過大拋 StackOverflowError | StackOverflowError / OOM |
| 本地方法棧 (Native Stack) | Native 方法執行內存模型 | 規格未強制規定結構;HotSpot 合併為 VM Stack | StackOverflowError / OOM |
虛擬機棧棧幀結構
+-------------------------+
| 附加信息 | ← 虛擬機實現自定義
+-------------------------+
| 返回地址 | ← 正常返回/異常返回恢復上層狀態
+-------------------------+
| 動態連接 | ← 指向運行時常量池方法引用,支持動態分派
+-------------------------+
| 操作數棧 | ← 計算中間結果、參數傳遞、返回值
+-------------------------+
| 局部變量表 | ← this、參數、局部變量(Slot 數組)
+-------------------------+
- 局部變量表:Slot 存基本類型、reference、returnAddress;
long/double 佔 2 Slot。方法入棧時分配,出棧釋放。
- 操作數棧:同樣基於 Slot,最大深度編譯期確定(
max_stack),單次計算複用空間。
- 動態連接:符號引用 → 直接引用,支撐多態調用(
invokevirtual)。
- 返回地址:保存調用者 PC,配合操作數棧傳遞返回值。
二、線程共享區域(進程級生命周期)
| 區域 | 核心內容 | 記憶體特徵 | GC 關聯 |
| Java 堆 (Heap) | 幾乎所有對象實例、數組 | 最大區域;邏輯連續、物理可不連續;分代:新生代/老年代 | GC 主戰場:Minor/Full GC |
| 方法區 (Method Area) | 類信息、常量、靜態變量、JIT 編譯代碼 | 邏輯上屬於堆;HotSpot 稱「永久代」(PermGen),JDK 8 移至元空間 | 常量池回收、類卸載 |
| 運行時常量池 | 類文件常量池載入後的運行時形態 | 屬於方法區子區域;含字面量、符號引用;動態性:String.intern() 可擴展 | 常量回收 |
堆內存分代模型
+------------------ Heap ------------------+
| Young Generation |
| Eden | Survivor0 (S0) | Survivor1 (S1)|
| | (From) | (To) |
+------------------+----------------------+
| Old Generation (Tenured) |
+-----------------------------------------+
| PermGen / Metaspace (JDK8+) | ← 方法區實現
+-----------------------------------------+
- 新生代:Eden : S0 : S1 = 8 : 1 : 1(可調),Minor GC 後存活對象在 S0/S1 間輪換,年齡達閾值晉升老年代。
- 老年代:大對象直接進老年代(
PretenureSizeThreshold),Full GC 觸發條件:老年代空間不足、元空間不足、System.gc()。
三、兩大經典異常對比
| 異常 | 成因 | 典型場景 | 排查方向 |
OutOfMemoryError | 區域無法申請更多物理內存或達參數上限 | 堆溢出、元空間溢出、直接內存溢出、線程創建過多 | Heap Dump (MAT/JVisualVM) 分析對象佔用、引用鏈 |
StackOverflowError | 棧幀深度超過虛擬機限制 | 遞歸無終止條件、大量方法嵌套調用、循環依賴調用 | -Xss 增加棧大小、檢查遞歸邏輯、-XX:+PrintStackTrace |
四、實戰調優參數速查
-Xms512m -Xmx2g # 堆初始/最大
-Xmn512m # 新生代大小
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m # 元空間
-Xss1m # 棧大小
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumps # OOM 自動導出
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/logs/gc.log # GC 日誌
理解運行時數據區,是定位內存洩漏、調優 GC、排查 OOM/StackOverflow 的地圖與羅盤。