前言
Java 自動內存管理機制釋放了開發者手動釋放內存的負擔,但也帶來了「不可控」的困惑。本文系統梳理 JVM 運行時區域、對象死亡判定算法、主流 GC 策略,幫助建立完整的內存管理知識體系。
一、JVM 運行時區域速覽

- 程序計數器:線程私有,字節碼行號指示器,用於線程切換恢復。
- 虛擬機棧:線程私有,方法調用棧幀,存局部變量表(基本類型、對象引用)。
- 本地方法棧:服務 Native 方法。
- 堆:線程共享,對象實例主存儲區,GC 主戰場。
- 方法區:線程共享,存類信息、常量、靜態變量、JIT 代碼,含運行時常量池。
二、對象已死?—— 存活判定算法
GC 核心任務:找出不可達對象並回收。
1. 引用計數法
給對象添加引用計數器,引用+1,釋放-1,計數為 0 即可回收。
缺陷:無法解決循環引用問題。
ObjA.instance = ObjB; ObjB.instance = ObjA;
兩對象互相引用計數不為 0,但實際已不可達。
2. 可達性分析法
主流 JVM 採用。以「GC Roots」為起點,向下搜索引用鏈,能到達的對象存活,不可達則判死。

GC Roots 包含:
- 虛擬機棧中引用的對象(局部變量表)
- 方法區中類靜態屬性引用的對象
- 方法區中常量引用的對象
- 本地方法棧中 JNI 引用的對象
三、垃圾回收策略(三大經典算法)
1. 標記-清除
- 過程:標記不可達對象 → 直接清除。
- 缺點:效率低(兩次掃描);產生大量內存碎片,導致大對象分配困難。
2. 複製算法
- 過程:內存劃分為等大 A、B 兩塊,每次用一塊。GC 時將存活對象複製到另一塊,然後清空已用塊。
- 缺點:內存利用率只有 50%,代價太大。
- 改進(新生代實踐):按 8:1:1 劃分 Eden、From、To。GC 時將 Eden+From 存活對象複製到 To,清空 Eden+From,角色互換。利用率達 90%。
3. 標記-整理
- 過程:標記後,將所有存活對象向一端移動,然後清理邊界外內存。
- 適用:老年代(存活率高,複製代價大),解決碎片問題。
四、參考資源
- 百度經驗:Java垃圾回收機制詳解
- 強烈推薦:Vamei - JVM垃圾回收原理
- 《深入理解Java虛擬機:JVM高級特性與最佳實踐》—— 周志明
總結
理解內存管理從「對象怎麼死」到「怎麼回收」的演進,是 Java 工程師進階的關鍵。可達性分析解決了引用計數的循環引用缺陷;分代收集理論建立在「弱分代假說」之上,新生代用複製,老年代用標記-整理。掌握這些原理,才能看懂 GC 日誌、調優堆參數、排查 OOM 與內存洩漏。