JVM
- 对象内存分配:
- 空间担保机制
- 案例演示:对象分配过程
- 01-大对象直接进入老年代
- 02-对象内存分配的过程:
- 案例演示:内存担保机制
对象内存分配:
- 新生代:新对象大多数都默认进入新生代的Eden区
- 进入老年代的条件:四种情况
- 存活年龄太大,默认超过15次【-XX:MaxTenuringThreshold】
- 动态年龄判断:MinorGC之后,发现Survivor区中的一批对象的总大小大于了这块Survivor区的50%,那么就会将此时大于等于这批对象年龄最大值的所有对象,直接进入老年代。
举个栗子:Survivor区中有一批对象,年龄分别为年龄1+年龄2+年龄n的多个对象,对象总和大小超过了Survivor区域的50%,此时就会把年龄n及以上的对象都放入老年代。
为什么会这样?希望那些可能是长期存活的对象,尽早进入老年代。
-XX:TargetSurvivorRatio可以指定- 大对象直接进入老年代:前提是Serial和ParNew收集器
举个栗子:字符串或数组
-XX:PretenureSizeThreshold 一般设置为1M
为什么会这样?为了避免大对象分配内存时的复制操作降低效率。避免了Eden和Survivor区的复制- MinorGC后,存活对象太多无法放入Survivor
空间担保机制
空间担保机制:当新生代无法分配内存的时候,我们想把新生代的老对象转移到老年代,然后把新对象放入腾空的新生代。此种机制我们称之为内存担保。
案例演示:对象分配过程
01-大对象直接进入老年代
package com.hero.jvm.object;
/**
* 测试:大对象直接进入到老年代
* -Xmx60m -Xms60m -XX:NewRatio=2 -XX:SurvivorRatio=8 -XX:+PrintGCDetails
* -XX:PretenureSizeThreshold
*
*/
public class YoungOldArea {
public static void main(String[] args) {
byte[] buffer = new byte[1024*1024*20]; //20M
}
}
-XX:NewRatio=2 新生代与老年代比值
-XX:SurvivorRatio=8 新生代中,Eden与两个Survivor区域比值
-XX:+PrintGCDetails 打印详细GC日志
-XX:PretenureSizeThreshold 对象超过多大直接在老年代分配,默认值为0,不限制
02-对象内存分配的过程:
案例演示:内存担保机制