現代 GC 採用可達性分析:從 GC Roots(棧幀局部變量、靜態字段、JNI 引用等)出發遍歷對象圖,標記存活對象,其餘視為垃圾。為獲取一致性快照,必須暫停所有應用線程(STW)。
兩條鐵律:
第二條優先級更高,寧可少回收些垃圾(浮動垃圾),不可誤傷存活對象。
Java 堆預先向 OS 申請大塊連續內存,後續分配在用戶態指針碰撞(Bump-the-Pointer)或空閒列表中完成,極快(接近棧分配速度)。
+------------------+ | PermGen | 類元數據、常量池、靜態變量 (Java 8 移除) +------------------+ | Heap | | +------------+ | | | Young Gen | | Eden + 2 Survivor (S0/S1) | +------------+ | | | Old Gen | | 長期存活對象 | +------------+ | +------------------+
虛擬空間允許各區動態伸縮而不移動對象。
「大多數對象朝生夕死,少數對象長期存活」—— 分代收集的理論基石。Young GC 頻繁、快;Old GC 耗時、少。
PermGen OOM,但監控工具需適配。| 參數 | 含義 |
|---|---|
-Xms/-Xmx | 堆初始/最大值(現代建議不設 -Xms 讓自適應調節) |
-XX:NewRatio=N | Old/Young 比例(默認 2:1) |
-XX:SurvivorRatio=N | Eden/Survivor 比例(默認 8:1:1) |
-XX:MaxTenuringThreshold=N | 進老年代年齡閾值(默認 15,CMS 6) |
-XX:+PrintGCDetails | 詳細 GC 日誌(必開) |
-Xloggc:file | 日誌輸出文件 |
-XX:+PrintTenuringDistribution | 年齡分佈統計(診斷過早晋升) |
原始日誌難讀,**務必用工具可視化**後再分析。
GC 不是黑盒。掌握分代模型、關鍵參數、日誌分析鏈路,配合可視化工具,即可從現象定位根因(如:Eden 太小導致頻繁 Young GC、大對象直入 Old 觸發 Full GC、Metaspace 增長未限制等),實施精準調優。