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

JVM 學習筆記(一):垃圾回收算法全景解析與 HotSpot 實踐

     編輯:Java 綜合教學

前言

垃圾回收 (GC) 是 Java 自動內存管理的核心支柱。理解 GC 算法原理、演進歷程及 HotSpot 具體實現,是排查內存問題、調優 JVM 參數、編寫高性能代碼的必修課。本文系統梳理 GC 觸發原因、四大基礎算法、分代收集策略、多線程 GC 模式,並配合內存結構圖解,構建完整知識體系。

一、垃圾回收存在的意義

  • 自動釋放無用對象內存:當對象不可達時,GC 回收其佔用空間供新對象使用
  • 消除內存碎片:整理堆內存,將存活對象移至一端,獲得大塊連續可用空間
  • 提升開發效率:程序員無需手動 malloc/free,專注業務邏輯
  • 保障程序完整性:防止懸空指針、雙重釋放等 C/C++ 常見內存錯誤

代價:GC 線程消耗 CPU 時間,可能導致應用停頓 (Stop-The-World),需權衡吞吐量與延遲。

二、對象存活判定算法

1. 引用計數法

  • 每個對象維護計數器,引用 +1,失效 -1,計數為 0 即可回收
  • 優點:實現簡單、效率高、即時回收
  • 致命缺陷:無法解決循環引用 (A→B, B→A 但無外部引用)
  • JDK 1.1 後廢棄,現代 JVM 均不使用

2. 根搜索算法 —— 現代 JVM 統一標準

GC Roots (根集合):

  • 虛棧棧幀中的局部變量表引用對象
  • 方法區類靜態屬性引用對象
  • 方法區常量引用對象
  • 本地方法棧 JNI 引用對象
  • 活躍線程、同步鎖持有對象、JVM 內部對象等

判定邏輯:從 GC Roots 出發向下搜索,可達路徑上的對象為存活對象,不可達對象為垃圾。

三、四大基礎回收算法

算法核心思想優點缺點適用場景
標記-清除
(Mark-Sweep)
1. 標記所有可回收對象
2. 統一清除
基礎算法,無需移動對象1. 效率低(雙遍歷)
2. 產生大量不連續碎片
老年代、存活率高區域
複製
(Copying)
內存劃分兩塊等大區域,每次用一塊,GC 時將存活對象複製到另一塊,清空已用區域1. 實現簡單、無碎片
2. 分配指針碰撞,速度極快
內存利用率只有 50%新生代(存活率極低 ~2%)
標記-整理
(Mark-Compact)
標記後,將存活對象向一端移動,直接清理邊界外內存1. 無碎片
2. 內存利用率高
需移動對象、更新引用,開銷大於複製老年代、存活率高區域
標記-清除-整理
(CMS 混合模式)
平時標記-清除,碎片超閾值時整理平衡停頓與碎片實現複雜低延遲要求場景

圖解對比

標記-清除:

GC 前:標記清除前

GC 後:標記清除後(碎片化)

複製算法:

GC 前:複製前

GC 後:複製後(無碎片,但浪費一半空間)

標記-整理:

GC 前:標記整理前

GC 後:標記整理後(無碎片,空間利用率高)

綠色:存活對象 紅色:可回收對象 白色:未使用空間

四、HotSpot 實戰:分代收集算法

核心假設:弱分代假設

  1. 絕大多數對象朝生夕死(新生代)
  2. 熬過多次 GC 的對象難以消亡(老年代)

堆內存分代結構

代特點算法典型收集器
新生代對象朝生夕死,存活率低 (~2%)複製算法 (8:1:1 Eden:S0:S1)Serial, ParNew, Parallel Scavenge
老年代對象存活率高,無額外空間分配擔保標記-清除 / 標記-整理Serial Old, Parallel Old, CMS, G1, ZGC


對象生命週期流轉

  1. 新對象優先分配在 Eden
  2. Eden 滿觸發 Minor GC,存活對象 → S0
  3. 後續 Minor GC:Eden + S0 存活 → S1,清空 Eden+S0,角色互換
  4. 年齡計數器達閾值 (默認 15,CMS 6) → 晋升老年代
  5. 大對象 (字節數組/長字符串) 直接進老年代 (PretenureSizeThreshold)
  6. 動態年齡判斷:Survivor 同齡對象總大小 > Survivor 一半,直接晋升

五、漸進式 GC 技術:避免長時間 STW

1. 增量收集 / 火車算法

將老年代劃分固定大小「車廂」,每次處理一車廂。理論優雅但實現極其複雜,HotSpot 未採用。

2. 分代收集 —— 產業標準

不同代、不同時期、不同算法,將一次全堆 GC 拆解為多次局部 GC,大幅降低單次停頓。

六、多線程 GC 實現模式

模式線程數STW優點缺點適用場景
串行 (Serial)1是無線程交互開銷,單核效率高無法利用多核單核、小堆 (<100MB)、Client 模式
並行 (Parallel)多是多核加速,吞吐量優先停頓時間長,隨堆增大而增長多核、批處理、科學計算、後台任務
並發 (Concurrent)多極短/無響應時間優先,用戶線程與 GC 線程並發CPU 開銷大、浮動垃圾、實現極其複雜Web 服務、GUI、電信交換、IDE

關鍵區別:

  • 並行:多條 GC 線程並行工作,用戶線程暫停
  • 並發:GC 線程與用戶線程同時運行(可能交替)

七、參考資源

八、下一站預告

本文提到了 Set 接口,下一筆記將深入探討 HashSet 實現原理,揭秘它如何「零代碼」複用 HashMap 實現去重語義。

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