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

JVM 調優總結(五):分代垃圾回收詳述(上)

     編輯:Java 相關知識

為什麼要分代?

核心假設:**弱代際假說** —— 「大多數對象朝生夕死,少數對象長期存活」。

  • **短命對象**:請求參數、臨時變量、String 構建中間對象等,生命週期極短。
  • **長命對象**:Session、線程池、緩存、連接池、配置類等,隨應用生命週期。

若不分代,每次 GC 掃描全堆,**長命對象被反覆掃描卻從不回收**,極大浪費 CPU。分代將不同壽命對象隔離,**針對性算法**大幅提效。

堆內存分代佈局

JVM 堆分代結構

新生代

  • **Eden 區**:所有新對象誕生地(TLAB 線程本地分配緩衝優化)。
  • **兩個 Survivor 區 (S0, S1)**:對稱、互換角色,**始終有一個為空**。
  • **流程**:
    1. Eden 滿 → Minor GC → 存活對象複製到 S0。
    2. 下次 Minor GC → Eden + S0 存活對象複製到 S1(S0 清空)。
    3. 反覆輪換,經歷 MaxTenuringThreshold 次仍存活 → 晉升老年代。
  • **動態年齡判定**:若 Survivor 區同齡對象總大小 > Survivor 容量 50%,直接晉升(不等年齡閾值)。

老年代

  • 存放**多次 Minor GC 仍存活**的對象、大對象(直接分配)、長期引用對象。
  • 回收算法:**標記-清除** 或 **標記-整理**(CMS 為前者,Parallel Old/G1 為後者)。

永久代 / 元空間

  • 存放 **Class 元數據、方法、常量池、靜態變量** 等。
  • JDK 8 移除永久代,改用**本地內存**實現的 **Metaspace**,默認無上限(受物理內存限制),可用 -XX:MaxMetaspaceSize 限制。
  • 動態生成類(JSP、反射、CGLIB、OSGi)易導致 OOM,需監控與調大。

GC 觸發條件分類

Minor GC (Scavenge GC)

  • **觸發**:Eden 區分配失敗(空間不足)。
  • **範圍**:僅掃描新生代 (Eden + Survivor)。
  • **特點**:頻繁、快速、高效(複製算法、存活少)。

Full GC (Major GC)

  • **觸發條件**(任一):
    1. 老年代 (Tenured) 寫滿。
    2. 永久代/元空間 寫滿。
    3. System.gc() 顯式調用(建議禁用,改用 -XX:+DisableExplicitGC)。
    4. 堆內存分配策略動態調整(如 CMS 晋升失敗、G1 混合收集失敗)。
  • **範圍**:全堆 (Young + Old + Perm/Metaspace)。
  • **特點**:耗時長(秒級),**調優核心目標 = 減少 Full GC 頻率與停頓**。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved