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

Java 記憶體管理核心:引用類型、垃圾回收機制與效能調優

     編輯:Java 相關知識

Java 無指標,只有引用

Java 設計之初即移除 C/C++ 指標,改用引用 存取物件。引用類型分四級,決定物件生命週期與 GC 回收時機:

引用類型強度GC 行為典型用途
強引用最強絕不回收 (OOM 拋出也不回收)一般物件 `Object obj = new Object()`
軟引用次之記憶體不足前回收快取 (`SoftReference`)、圖片緩存
弱引用弱下次 GC 必回收觀察者模式、`WeakHashMap`、ThreadLocal
虛引用最弱任何時候可回收,需配合 ReferenceQueue直接記憶體釋放追蹤、Cleaner 機制

垃圾回收核心演算法

  • 可達性分析:從 GC Roots (棧區引用、靜態欄位、常數、JNI 等) 出發,不可達即為垃圾。
  • 分代假說:多數物件朝生夕死 (新生代),少數長期存活 (老年代)。
  • 三大演算法:
    • 標記-清除:碎片化嚴重。
    • 標記-整理:無碎片,需移動物件。
    • 複製:新生代適用,浪費一半空間 (Eden + 2 Survivor)。

主流收集器演進

收集器模式新生代/老年代特點適用場景
Serial單執行緒兩者簡單、Client 模式預設單核、小記憶體
Parallel (PS)多執行緒兩者高吞吐、Server 模式預設 (Java 8)批次處理、科學計算
CMS併發老年代低停頓、碎片化、Java 9 棄用、Java 14 移除舊版低延遲需求
G1併發+分區兩者可預測停頓、Region 架構、Java 9+ 預設大堆 (6G+)、微服務
ZGC併發+著色指標兩者亞毫秒停頓、TB 級堆、Java 11 實驗/15 正式超大堆、極低延遲
Shenandoah併發+轉發指標兩者類 ZGC、Red Hat 主導、Java 12+大堆、低延遲

常見記憶體問題與診斷

1. 記憶體洩漏 (邏輯引用未釋放)


// 典型:靜態集合持續增長
public class LeakExample {
    private static final List CACHE = new ArrayList<>();
    public void add(Object o) { CACHE.add(o); } // 永不移除
}

// 修正:用 WeakHashMap、設定過期清理、或手動 remove


2. OOM 排查步驟

  1. 啟動參數:`-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumps`
  2. 工具分析:Eclipse MAT (支配者樹、洩漏嫌疑)、JVisualVM、Arthas (線上診斷)。
  3. 關鍵指標:`retained size` 大的物件、`GC Root` 到物件的引用鏈。

3. Finalizer 陷阱

`finalize()` 不保證執行、拖慢 GC、Java 9 棄用。資源釋放請用 try-with-resources、`AutoCloseable` 或 `Cleaner` (Java 9+)。

效能調優實戰參數


# 基礎堆設定 (生產建議 Xms=Xmx 避免震盪)
-Xms4g -Xmx4g

# 新生代/老年代比例
-XX:NewRatio=2        # 老年代:新生代 = 2:1
-XX:SurvivorRatio=8   # Eden:Survivor = 8:1:1

# 選擇收集器 (三選一)
-XX:+UseG1GC                    # 通用首選
-XX:+UseZGC -XX:+ZGenerational  # JDK 21+ 分代 ZGC,超大堆
-XX:+UseShenandoahGC            # 替代方案

# G1 關鍵目標
-XX:MaxGCPauseMillis=200  # 目標停頓時間
-XX:G1HeapRegionSize=16m  # Region 大小 (1-32MB,堆大則調大)

# 診斷日誌 (統一格式 JDK 9+)
-Xlog:gc*:file=/logs/gc.log:time,uptime,level,tags:filecount=5,filesize=100m

現代最佳實踐

  1. 預設用 G1 (JDK 8u20+ / 9+),僅在超大堆 (16G+) 且極致低延遲需求下評估 ZGC/Shenandoah。
  2. 避免手動 `System.gc()`,信任擴展適應性調節 (`-XX:+UseAdaptiveSizePolicy`)。
  3. 大物件直接進老年代:`-XX:PretenureSizeThreshold=1m` (僅 Serial/Parallel/G1 有效)。
  4. 監控指標:GC 頻率、停頓分佈、老年代增長趨勢、Metaspace 使用量。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved