JVM 动态年龄判断规则

JVM 动态年龄判断规则,第1张

JVM 动态年龄判断规则

对象进入老年代的动态年龄判断规则(动态晋升年龄计算阈值):Minor GC 时,Survivor 中年龄 1 到 N 的对象大小超过 Survivor 的 50% 时,则将大于等于年龄 N 的对象放入老年代。

《深入理解 Java 虚拟机》书中对动态年龄判断规则的解释大致是:同龄对象大小超过 50% 时,则将大于等于该年龄的对象放入老年代。

以前看到这块的时候一直觉得有点不太理解,因为如果是同龄对象的话,那么这批放入老年代的对象就必然是 1 岁,因为如果在 1 岁的时候没有达到 50%,那么在之后就更不可能达到 50% 了。但也没太在意,直到最近又开始学习 JVM 相关知识,才发现了不一样的解释,囧。

验证:
public class TestTargetSurvivorRatio {
    private static final int MB = 1024 * 1024;
    public static void main(String[] args) throws InterruptedException {
        byte[] b1 = new byte[MB * 33];
        byte[] b2 = new byte[MB * 33];
        byte[] a1 = new byte[MB * 3];
        b1 = null;
        b2 = null;
        System.out.println("--------1 start");
        b1 = new byte[MB * 33];
        // 垃圾回收完成后:
        // 大概1M的系统垃圾+3M的a1进入Survivor,垃圾回收完成后,这些对象就是年龄1
        System.out.println("--------1 end");
        b2 = new byte[MB * 33];
        byte[] a2 = new byte[MB * 3];
        b1 = null;
        b2 = null;
        System.out.println("--------2 start");
        // 垃圾回收前,Survivor中的对象年龄1到N的大小不足50%
        // 因此在回收的时候年龄1的对象不会进入老年代
        b1 = new byte[MB * 33];
        // 垃圾回收完成后:
        // Survivor中原有的大概1M的系统垃圾+3M的a1变成年龄2
        // 新进入Survivor的3M的a2就是年龄1
        System.out.println("--------2 end");
        b2 = new byte[MB * 33];
        byte[] a3 = new byte[MB * 3];
        b1 = null;
        b2 = null;
        System.out.println("--------3 start");
        // 垃圾回收前,年龄2有大概4M,年龄1大概有3M,超过Survivor的50%
        // 因此在回收的时候年龄2的4M会进入老年代
        b1 = new byte[MB * 33];
        // 垃圾回收完成后:
        // Survivor中3M的a2年龄变成2
        // 新进入的3M的a3为年龄1
        // 老年代中的则是原先的系统大概1M和3M的a1
        System.out.println("--------3 end");
    }
}

设置以下 JVM 参数,运行上述代码

-Xmx200M
-Xms200M
-Xmn100M
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=15
-XX:PretenureSizeThreshold=100M
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
最终运行结果:( jdk 8)
--------1 start
0.192: [GC (Allocation Failure) 0.192: [ParNew: 77214K->4000K(92160K), 0.0028037 secs] 77214K->4000K(194560K), 0.0029006 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
--------1 end
--------2 start
0.208: [GC (Allocation Failure) 0.208: [ParNew: 76242K->7255K(92160K), 0.0044250 secs] 76242K->7255K(194560K), 0.0044863 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
--------2 end
--------3 start
0.225: [GC (Allocation Failure) 0.225: [ParNew: 81144K->6339K(92160K), 0.0044202 secs] 81144K->10187K(194560K), 0.0044672 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
--------3 end
Heap
 par new generation   total 92160K, used 42536K [0x00000000f3800000, 0x00000000f9c00000, 0x00000000f9c00000)
  eden space 81920K,  44% used [0x00000000f3800000, 0x00000000f5b59160, 0x00000000f8800000)
  from space 10240K,  61% used [0x00000000f9200000, 0x00000000f9830f80, 0x00000000f9c00000)
  to   space 10240K,   0% used [0x00000000f8800000, 0x00000000f8800000, 0x00000000f9200000)
 concurrent mark-sweep generation total 102400K, used 3847K [0x00000000f9c00000, 0x0000000100000000, 0x0000000100000000)
 Metaspace       used 3330K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 359K, capacity 388K, committed 512K, reserved 1048576K

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/876964.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存