Jvm对象进入老年代的四种场景

1、大对象直接进入老年代

   大对象就是需要大量连续内存空间的对象(比如:字符串、数组)。JVM参数
XX:PretenureSizeThreshold 可以设置大 对象的大小,如果对象超过设置大小会直接进入老年
代,不会进入年轻代,这个参数只在 Serial 和ParNew两个收集器下 有效。比如设置JVM参数:
-XX:PretenureSizeThreshold=1000000 (单位是字节) -XX:+UseSerialGC ,再执行下上
面的第一 个程序会发现大对象直接进了老年代 

为什么要这样呢?(原因) 
为了避免为大对象分配内存时的复制操作而降低效率。

2、长期存活的对象将进入老年代

	  既然虚拟机采用了分代收集的思想来管理内存,那么内存回收时就必须能识别哪些对象应
    放在新生代,哪些对象应放在 老年代中。为了做到这一点,虚拟机给每个对象一个对象年龄
	(Age)计数器。 如果对象在 Eden 出生并经过第一次 Minor GC 后仍然能够存活,并且
	能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并将对象年龄设为1。对象在 
	Survivor 中每熬过一次 MinorGC,年龄就增加1岁,当它的年龄增加到一定程度 (默认为
	15岁,CMS收集器默认6岁,不同的垃圾收集器会略微有点不同),就会被晋升到老年代中。
	对象晋升到老年代 的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 来设置。

3、对象动态年龄判断

		当前放对象的Survivor区域里(其中一块区域,放对象的那块s区),一批对象的总大小
	大于这Survivor区域内存大小的 50%(-XX:TargetSurvivorRatio可以指定),那么此时
	大于等于这批对象年龄最大值的对象,就可以直接进入老年代了, 例如Survivor区域里现
	在有一批对象,年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%,此时
	就会 把年龄n(含)以上的对象都放入老年代。这个规则其实是希望那些可能是长期存活的对
	象,尽早进入老年代。
	
	对象动态年 龄判断机制一般是在minor gc之后触发的。

4、 老年代空间分配担保机制

	年轻代每次minor gc之前JVM都会计算下老年代剩余可用空间 如果这个可用空间小于年轻代
里现有的所有对象大小之和(包括垃圾对象) 就会看一个“-XX:-HandlePromotionFailure”
(jdk1.8默认就设置了)的参数是否设置了 如果有这个参数,就会看看老年代的可用内存大小,
是否大于之前每一次minor gc后进入老年代的对象的平均大小。 如果上一步结果是小于或者之
前说的参数没有设置,那么就会触发一次Full gc,对老年代和年轻代一起回收一次垃圾, 如果
回收完还是没有足够空间存放新的对象就会发生"OOM" 当然,如果minor gc之后剩余存活的需
要挪动到老年代的对象大小还是大于老年代可用空间,那么也会触发full gc,full gc完之后如
果还是没有空间放minor gc之后的存活对象,则也会发生“OOM”

你可能感兴趣的:(java)