核心觀念:JVM 記憶體管理機制
Java 的垃圾回收(GC)是 JVM 記憶體管理的核心。當物件在堆內存中不再被任何「根集合」(靜態變數、區域變數、JNI 參考等)直接或間接引用時,即成為可回收的垃圾物件。開發者無法手動釋放記憶體,一切交由 JVM 自動管理。
堆與棧記憶體劃分
堆記憶體
- JVM 啟動時建立,存放
new 出來的物件實例
- 分為新生代(Eden、From Survivor、To Survivor)與老年代
- 新物件優先分配在 Eden,滿觸發 Minor GC,存活物件在 Survivor 區來回複製,年齡達閾值晉升老年代
- 老年代物件生命週期長,Major GC 頻率低但耗時久
棧記憶體
存放方法調用幀、區域變數、方法參數等,隨線程生命週期同步,不涉及 GC。
物件完整生命週期七階段
- 建立階段:分配記憶體 → 初始化結構 → 父類 static 初始化 → 父類實例初始化 → 子類實例初始化
- 使用階段:持有強引用,可觸達;亦可使用軟/弱/虛引用實現快取等進階場景
- 不可見階段:區域變數超出作用域,程式碼無法再引用
- 不可達階段:根集合搜尋不到任何強引用路徑
- 可收集階段:GC 判定可回收
- 終結階段:執行
finalize()(已棄用,不建議依賴)
- 釋放階段:記憶體歸還堆空間
四種引用類型對比
| 引用類型 | 回收時機 | 典型用途 |
| 強引用 | 永不回收(OOM 也拋異常) | 一般物件持有 |
| 軟引用 | 記憶體不足前回收 | 快取、記憶體敏感資源 |
| 弱引用 | 下次 GC 必回收 | WeakHashMap、監聽器 |
| 虛引用 | 需配合 ReferenceQueue | 輔助 finalize、直接記憶體釋放 |
開發建議
- 避免循環內建立大量物件
- 及時置空不再使用的引用(
obj = null)
- 慎用
System.gc(),讓 JVM 自行決定最佳時機
- 大物件、長生命週期且非高頻存取者優先考慮軟引用