首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JVM 垃圾回收核心機制深度解析:從引用計數到分代收集

     編輯:Java 相關知識

垃圾回收 (GC) 是 Java 自動記憶體管理的基石。本文系統講解 GC 的判定演算法、主流收集器類型、JVM 實作演進,並給出調優關鍵點,幫助開發者理解 JVM 記憶體行為、排查 OOM 與長停頓問題。

物件存活判定:兩大經典演算法

引用計數法

每個物件維護一個計數器,引用+1,失效-1,歸零即可回收。優點:即時性強、停頓極短。致命缺陷:無法解決循環引用(A→B、B→A 計數永不歸零),早期 JVM 已棄用。

可達性分析(根搜索/追蹤收集)

從 GC Roots(棧帧局部變數、靜態屬性、常數、JNI 引用等)出發,走對象圖標記可達物件。不可達者判定為垃圾。現代所有主流 JVM(HotSpot、OpenJ9、Zing 等)均採用此法。

三大經典收集演算法

演算法核心思想優點缺點
標記-清除標記可達 → 掃描堆釋放不可達實作簡單記憶體碎片化嚴重
標記-整理標記後將存活物件向一端移動無碎片需移動物件、更新引用,耗時較長
複製劃分 From/To 兩區,存活物件複製到 To 區分配極快(指針碰撞)、無碎片浪費 50% 空間;長壽命物件頻繁複製開銷大

HotSpot 分代收集策略

基於「弱分代假說」:多數物件朝生夕死、少數長期存活。堆劃分為:

  • 新生代:Eden + 2 個 Survivor(S0/S1),採用複製演算法,Minor GC 頻繁且快。
  • 老年代:長壽命物件,採用標記-整理,Major/Full GC 耗時長。

主流垃圾收集器對比

收集器代演算法線程特點
Serial新/老複製/標記-整理單線程Client 模式預設,停頓長
ParNew新複製多線程Serial 多線程版,配合 CMS
Parallel Scavenge新複製多線程吞吐量優先,自適應調優
CMS老標記-清除多線程低停頓,碎片化、浮動垃圾
G1混合標記-整理+複製多線程區域化、可預測停頓,JDK 9+ 預設
ZGC / Shenandoah全堆並發整理多線程亞毫秒級停頓,大堆(TB 級)首選

開發者必知的 GC 細節

  1. finalize() 僅執行一次,異常不阻礙回收,不建議依賴它釋放資源(改用 try-with-resources / Cleaner)。
  2. 物件在 finalize() 中「復活」僅生效一次,下次 GC 直接回收。
  3. System.gc() 僅是建議,JVM 可忽略;生產環境避免顯式調用。
  4. 記憶體洩漏本質:長生命周期物件持有短生命周期物件引用(如靜態集合、未關閉的流、監聽器未移除)。
追蹤收集器示意圖

圖示:根節點可達性分析標記過程

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved