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];
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");
b1 = new byte[MB * 33];
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");
b1 = new byte[MB * 33];
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
|