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

MaxTenuringThreshold 參數深度解讀:對象晉升老年代的動態判斷邏輯並非固定閾值

     編輯:Java 相關知識

-XX:MaxTenuringThreshold 默認 15,但對象並非必須經歷 15 次 Minor GC 才晉升老年代。HotSpot 在每次 Minor GC 後動態計算新的存活年齡閾值,取 age 與 MaxTenuringThreshold 的較小值。

動態閾值計算算法(Serial/ParNew GC)

size_t desired_survivor_size = survivor_capacity * TargetSurvivorRatio / 100; // 目標Survivor佔用量(默認50%)
size_t total = 0;
int age = 1;
while (age < table_size) {
    total += sizes[age]; // 累加各年齡對象大小
    if (total > desired_survivor_size) break; // 超過目標則停止
    age++;
}
int result = Math.min(age, MaxTenuringThreshold);

實戰驗證代碼

public class GCTenuringThreshold {
    public static void main(String[] args) throws Exception {
        GCMemoryObject o1 = new GCMemoryObject(2); // 512KB
        GCMemoryObject o2 = new GCMemoryObject(8); // 2MB
        GCMemoryObject o3 = new GCMemoryObject(8);
        GCMemoryObject o4 = new GCMemoryObject(8);
        o2 = null; o3 = null;
        GCMemoryObject o5 = new GCMemoryObject(8);
        Thread.sleep(4000);
        o2 = new GCMemoryObject(8); o3 = new GCMemoryObject(8);
        o2 = null; o3 = null; o5 = null;
        GCMemoryObject o6 = new GCMemoryObject(8);
        Thread.sleep(5000);
    }
}
class GCMemoryObject { byte[] bytes; GCMemoryObject(int m) { bytes = new byte[1024*256*m]; } }

參數 -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC,jstat -gcutil pid 1000 10 觀察:o1 在第 2 次 Minor GC 即晉升老年代(年齡 1),因首次 GC 後動態閾值計算為 1。

適用範圍與差異

  • Serial GC / ParNew GC(未開啟 UseAdaptiveSizePolicy):上述算法生效
  • ParNew GC(開啟 UseAdaptiveSizePolicy):算法失效,默認關閉
  • Parallel Scavenge (PS) GC:默認用 InitialTenuringThreshold=7,之後動態計算(規則更複雜);-XX:-UseAdaptiveSizePolicy 固定為 MaxTenuringThreshold

監控動態閾值

啟動參數添加 -XX:+PrintTenuringDistribution,日誌輸出:

Desired survivor size 1048576 bytes, new threshold 7 (max 15)

new threshold 即當前動態年齡閾值。

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