Java 中的垃圾回收
GC 核心兩步:判斷垃圾對象 → 回收釋放內存。
一、垃圾對象判斷:可達性分析

從 GC Roots 出發向下搜索,不可達對象即為垃圾。GC Roots 包含:
- Class:系統類加載器加載的類(靜態字段持有對象)。
- Thread:活躍線程。
- Stack Local:Java 方法局部變量/參數。
- JNI Local/Global:JNI 本地/全局引用。
- Monitor Used:同步鎖持有對象。
- Held by JVM:JVM 內部保留對象(異常類、類加載器等)。
二、回收算法
- 複製算法:內存劃分兩塊,每次用一塊,存活對象複製到另一塊,一次性清理。優點:無碎片;缺點:內存利用率 50%。
- 標記-清除:標記垃圾統一清除。缺點:效率低、產生大量不連續碎片。
- 標記-整理:標記後將存活對象向一端移動,清理邊界外內存。解決碎片問題。

三、分代回收策略
根據對象生命周期劃分代,針對性選擇算法:
- 新生代:對象朝生夕死,採用複製算法。分 Eden、From Survivor、To Survivor。Minor GC 將存活對象在 Survivor 間複製,經過多次 GC 仍存活則晉升老年代。
- 老年代:對象存活率高,採用標記-清除或標記-整理。
四、GC 類型與 Full GC 觸發條件
- Scavenge GC (Minor GC):針對 Eden 區。
- Full GC (Major GC):掃描整個堆 (Young + Tenured + Perm)。調優核心在於減少 Full GC 次數。
Full GC 觸發條件:
- 老年代 (Tenured) 滿。
- 持久代 (Perm/Metaspace) 滿。
- 顯式調用
System.gc()。
- 堆分配策略動態變化。
參考:《深入理解 Java 虛擬機》、GC 詳細分析