在 JVM 中,垃圾回收(GC)是核心機制之一。為了提升性能與內存利用率,JVM 采用了多種垃圾回收算法。本文總結了 四種常見的 GC 算法,并結合其優缺點與應用場景進行說明。
1. 標記-清除(Mark-Sweep)
工作流程
標記:從 GC Roots 出發,標記所有存活對象。
清除:回收未標記的對象,釋放內存空間。
優點
實現簡單。
不需要對象移動。
缺點
會產生 內存碎片,導致大對象分配困難。
標記和清理效率相對較低。
應用
常用于 老年代(Old Generation) 的早期實現。
2. 標記-整理(Mark-Compact)
工作流程
標記:標記存活對象。
整理:將存活對象移動到一端,按順序排列,清理邊界外的內存。
優點
消除了 內存碎片。
內存利用率更高。
缺點
需要移動對象,成本較高(復制和更新引用)。
應用
常用于 老年代。
👉 老年代對象存活率高、體積大,不能用復制算法(浪費內存),也不適合只用標記-清除(碎片多),因此更適合標記-整理。
3. 復制算法(Copying)
工作流程
將內存分為兩塊相等的區域(From、To)。
每次只使用一塊區域(From)。
GC 時,把存活對象復制到另一塊區域(To),然后清空 From。
優點
無內存碎片。
內存分配只需移動指針,效率高。
缺點
內存利用率低(只能使用一半空間)。
復制存活對象需要開銷。
應用
常用于 新生代(Young Generation)。
👉 新生代對象生命周期短,大部分很快被回收,存活率低,復制的開銷不大。
4. 分代收集(Generational Collection)
核心思想
不同對象的生命周期不同,采用不同的回收算法:
新生代:存活率低 → 使用 復制算法,效率高。
老年代:存活率高、對象大 → 使用 標記-清除 或 標記-整理。
優點
綜合利用不同算法的優勢。
性能和內存利用率較高。
缺點
實現復雜。
應用
HotSpot JVM 主流實現就是基于分代收集思想的(新生代 + 老年代)。
總結對比表
算法 | 原理 | 優點 | 缺點 | 應用場景 |
---|---|---|---|---|
標記-清除 | 標記存活對象,清理未標記對象 | 實現簡單 | 有碎片,效率低 | 老年代(早期) |
標記-整理 | 標記存活對象并移動整理 | 無碎片 | 對象移動,成本高 | 老年代 |
復制算法 | 復制存活對象到另一塊區域 | 快,無碎片 | 浪費內存(50%利用率) | 新生代 |
分代收集 | 新生代復制 + 老年代標記整理 | 綜合性能好 | 實現復雜 | 主流 JVM 使用 |
總結:
新生代:對象生命周期短 → 復制算法。
老年代:對象大、存活率高 → 標記-整理。
分代收集:融合多種算法,實際生產環境的主流方案。