JVM 模拟对象进入老年代的四种情况

JVM 模拟对象进入老年代的四种情况

github

1、JVM参数设置

JVM参数设置(JDK1.8)
-XX:InitialHeapSize=20971520
-XX:MaxHeapSize=20971520
-XX:NewSize=10485760
-XX:MaxNewSize=10485760
-XX:SurvivorRatio=8/3
-XX:MaxTenuringThreshold=15/5
-XX:PretenureSizeThreshold=10485760/5242880
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:gc.log

2、模拟通过动态年龄判定规则进入老年代:如果Survivor区域 年龄1+...+年龄n 对象总和大于Survivor区域的50%,年龄n以上的对象会进入老年代。

2.1.Java代码

public class GCDemo_02 {

	public static void main(String[] args) {
		/**
		 * 创建三个2M大小的数组
		 * 将array_1设置为null
		 */
		byte[] array_1 = new byte[2 * 1024 * 1024];
		array_1 = new byte[2 * 1024 * 1024];
		array_1 = new byte[2 * 1024 * 1024];
		array_1 = null;
		/**
		 * 创建一个128k大小的数组
		 */
		byte[] array_2 = new byte[128 * 1024];
		/**
		 * 创建一个2M大小的数组
		 * Eden区域内存不够发生GC
		 */
		byte[] array_3 = new byte[2 * 1024 * 1024];
		/**
		 * 创建两个2M大小的数组,一个128K大小的数组
		 * 将array_3设置为null
		 */
		array_3 = new byte[2 * 1024 * 1024];
		array_3 = new byte[2 * 1024 * 1024];
		array_3 = null;
		/**
		 * 创建一个2M大小的数组
		 * Eden区域内存不够发生GC,GC过后的内存加上Survivor的内存大于Survivor内存的50%,将Survivor内存数据放入老年代
		 */
		byte[] array_4 = new byte[2 * 1024 * 1024];
	}
	
}

2.2.过程分析

1、新生代大小20M,Eden大小8M,from大小1M,to大小1M,JVM系统使用内存大小1M(GCDemo_00得知)。
2、第一次YoungGC
	1.创建三个2M的数组,然后将其设置为null,表示其可以被GC回收。
	2.创建一个128K的数组,这是通过动态年龄规则进入老年代的内存。
	3.此时Eden内存大小 3*2M + 1M + 128K = 7M 多一点。
	4.创建一个2M的数组,Eden内存不够将触发YoungGC。
3、第一次YoungGC后内存情况
	1.Eden区域有一个2M的数组(array_3)。
	2.from区域有一个128K的数组(array_2)和JVM系统使用的一部分内存一共677K,占比66%,超过了50%。
	3.Old区域为空。
4、第二次YoungGC
	1.创建两个2M的数组,然后将其设置为null,表示其可以被GC回收。
	2.此时Eden内存大小 2M + 2M*2 + 1M = 7M 多一点。
	3.创建一个2M的数组,Eden内存不够将触发YoungGC。
5、第二次YoungGC后内存情况
	1.Eden区域有一个2M的数组(array_4)。
	2.from区域为空。根据动态年龄判定规则进入老年代。
	3.Old区域有一个128K的数组(array_2)和JVM系统使用的一部分内存一共677K。

3、模拟躲过指定年龄阈值进入老年代

3.1.Java代码

public class GCDemo_03 {

	public static void main(String[] args) {
		byte[] array_1 = new byte[2 * 1024 * 1024];
		array_1 = new byte[2 * 1024 * 1024];
		array_1 = null;
		
		byte[] array_2 = new byte[128 * 1024];
		
		byte[] array_3 = new byte[1 * 1024 * 1024];
		array_3 = new byte[1 * 1024 * 1024];
		array_3 = new byte[1 * 1024 * 1024];
		array_3 = new byte[1 * 1024 * 1024];
		array_3 = new byte[1 * 1024 * 1024];
		array_3 = null;
		
		byte[] array_4 = new byte[1024 * 1024];
		array_4 = new byte[1 * 1024 * 1024];
		array_4 = new byte[1 * 1024 * 1024];
		array_4 = new byte[1 * 1024 * 1024];
		array_4 = new byte[1 * 1024 * 1024];
		array_4 = null;
		
		byte[] array_5 = new byte[1 * 1024 * 1024];
		array_5 = new byte[1 * 1024 * 1024];
		array_5 = new byte[1 * 1024 * 1024];
		array_5 = new byte[1 * 1024 * 1024];
		array_5 = new byte[1 * 1024 * 1024];
		array_5 = null;

		byte[] array_6 = new byte[1 * 1024 * 1024];
		array_6 = new byte[1 * 1024 * 1024];
		array_6 = new byte[1 * 1024 * 1024];
		array_6 = new byte[1 * 1024 * 1024];
		array_6 = new byte[1 * 1024 * 1024];
		array_6 = null;
		
		
		byte[] array_7 = new byte[1 * 1024 * 1024];
		array_7 = new byte[1 * 1024 * 1024];
		array_7 = new byte[1 * 1024 * 1024];
		array_7 = new byte[1 * 1024 * 1024];
		array_7 = new byte[1 * 1024 * 1024];
		array_7 = null;
		
		byte[] array_8 = new byte[1 * 1024 * 1024];
	}
	
}

3.2.过程分析

1、新生代大小20M,Eden大小6M,from大小2M,to大小2M,JVM系统使用内存大小1M(GCDemo_00得知)。
2、第一次GC
	1.创建两个2M的数组,然后将其设置为null,表示其可以被GC回收。
	2.创建一个128K的数组,这是躲过指定年龄阈值进入老年代的对象。
	3.此时Eden内存大小 2*2M + 1M + 128K = 5M 多一点。
	4.创建一个1M的数组,Eden内存不够将触发YoungGC。
3、第二次GC
	1.创建4个1M的数组,然后将其设置为null,表示其可以被GC回收。
	2.此时Eden区域内存大小 4*1M + 1M = 5 M 多一点。
	4.创建一个1M的数组,Eden内存不够将触发YoungGC。
4、第三次GC。
5、第四次GC。
6、第五次GC。
7、第六次GC。此时128K的数组(array_2)和JVM系统使用的一部分内存一共677K躲过了指定年龄阈值进入老年代。

4、模拟YoungGC过后对象因为放不下Survivor区域直接进入老年代

4.1.Java代码

public class GCDemo_04 {

	public static void main(String[] args) {
		byte[] array_1 = new byte[2 * 1024 * 1024];
		array_1 = new byte[2 * 1024 * 1024];
		array_1 = new byte[2 * 1024 * 1024];
		
		byte[] array_2 = new byte[128 * 1024];
		array_2 = null;
		
		byte[] array_3 = new byte[2 * 1024 * 1024];
	}
	
}

4.2.过程分析

1、新生代大小20M,Eden大小8M,from大小1M,to大小1M,JVM系统使用内存大小1M(GCDemo_00得知)。
2、第一次GC
	1.创建三个2M的数组,让后让array_1指向第三个数组,表示前两个数组可以被GC回收。
	2.创建一个128的数组,将其设置为null。
	3.此时Eden内存大小 2*3M + 1M + 128K = 7M 多一点。
	4.创建一个2M的数组,Eden内存不够将触发YoungGC。
3、第一次GC后内存情况
	1.Eden区域一个2M的数组(array_3)。
	2.from区域是JVM系统使用的一部分内存。
	3.Old区域一个2M的数组(array_1)。

5、模拟大对象直接进入老年代

5.1.Java代码

public class GCDemo_05 {

	public static void main(String[] args) {
		byte[] array_2 = new byte[5 * 1024 * 1024];
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值