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

JVM 記憶體分配與回收策略深度解析

     編輯:Java 綜合教學

JVM 記憶體分配與回收策略深度解析

Java 虛擬機 (JVM) 的記憶體管理機制是 Java 技術體系的核心基石之一。理解物件如何分配、何時回收、以及不同代之間的流轉規則,對於效能調優與問題排查至關重要。本文系統梳理 JVM 中的記憶體分配與垃圾回收核心策略。

1. 物件優先在 Eden 區分配

絕大多數物件誕生於新生代的 Eden 區。當 Eden 區空間不足以容納新物件時,虛擬機將觸發一次 Minor GC (新生代垃圾收集)。由於 Java 物件多具備「朝生夕滅」特性,Minor GC 頻率極高,但耗時通常較短。

相對應地,Major GC (或 Full GC) 發生在老年代,速度往往比 Minor GC 慢 10 倍以上。值得注意的是,Major GC 通常伴隨至少一次 Minor GC,但 Parallel Scavenge 收集器等特定策略可能直接觸發 Major GC。

2. 大物件直接進入老年代

所謂大物件,指需要大量連續記憶體空間的 Java 物件,典型例子包括極長的字串與陣列。為避免在 Eden 區與兩個 Survivor 區之間發生大量記憶體複製開銷,虛擬機提供了 -XX:PretenureSizeThreshold 參數,令大於此閾值的物件直接在老年代分配。

3. 長期存活物件將晉升老年代

虛擬機為每個物件定義了年齡計數器。物件在 Eden 區誕生並經過首次 Minor GC 後仍存活,且能被 Survivor 區容納時,會被移至 Survivor 區並將年齡設為 1。其後每經歷一次 Minor GC,年齡增 1。當年齡達到閾值 (預設 15,可透過 -XX:MaxTenuringThreshold 調整) 時,物件將晉升至老年代。

4. 動態物件年齡判定

為適應不同程式的記憶體狀況,虛擬機並非強制要求物件年齡必須達到 MaxTenuringThreshold 才能晉升。若在 Survivor 空間中,相同年齡所有物件大小總和大於 Survivor 空間的一半,則年齡大於或等於該年齡的物件可直接進入老年代,無需等待達到最大年齡閾值。

5. 空間分配擔保

在發生 Minor GC 前,虛擬機會檢查老年代最大可用連續空間是否大於新生代所有物件總空間。若條件成立,Minor GC 安全可行;否則虛擬機檢查 HandlePromotionFailure 設定是否允許擔保失敗。若允許,則進一步比對老年代最大可用連續空間與歷次晉升老年代物件平均大小;若前者較大,嘗試進行一次有風險的 Minor GC;若較小或不允許冒險,則改為執行 Full GC。

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