1. 老年代GC
- JVM参数:
-Xmx20m -Xms20m -Xmn10m -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15 -XX:PretenureSizeThreshold=3m
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:log/demo5.log
- 示例代码:
public class Demo5 {
public static void main(String[] args) {
byte[] array1 = new byte[4 * 1024 * 1024];
array1 = null;
byte[] array2 = new byte[2 * 1024 * 1024];
byte[] array3 = new byte[2 * 1024 * 1024];
byte[] array4 = new byte[2 * 1024 * 1024];
byte[] array5 = new byte[2 * 1024 * 1024];
}
}
1.1 代码执行流程
JVM参数:
Xmx20m -Xms20m -Xmn10m -XX:SurvivorRatio=8
:新生代10M,按比例Eden区8M,老年代10M;-XX:PretenureSizeThreshold=3m
,手动设置了大对象阈值为3M;
首先创建array1指向的4M的byte数组对象,它大于了大对象阈值,所以会直接进入老年代;
且把array1指向了null,即在老年代的这个4M对象是垃圾对象;
然后连续创建 array2、array3、array4指向的2M的byte数组对象,它们都一直被引用,且小于大对象阈值,所以它们都在新生代中;
在继续创建array5指向的2M对象的时候,由于Eden区大小为8M,此时放不下这个2M对象了,就会发生一次新生代GC(Young GC);
在发生这次GC的时候,array2、array3、array4的一共6M对象都是存活的,Survivor区肯定是放不下它们的,所以它们会通过分配担保原则进入老年代;
在进入老年代的时候,此时老年代已经有了4M的对象;老年代大小为10M,可以放入array2,array3的4M对象,继续放入array4的2M对象时,老年代不够了,所以需要进行一次老年代GC来回收老年代,才能继续放入array4的2M对象;
1.2 GC日志分析
Java HotSpot(TM) 64-Bit Server VM (