然后把存活对象都放入第一个Survivor区域中,也就是S0区域
接着垃圾回收器就会直接回收掉Eden区里剩余的全部垃圾对象,在整个这个垃圾回收的过程中全程会进入Stop the Wold状态,也就 是暂停系统工作线程,系统代码全部停止运行,不允许创建新的对象
只有这样,才能让垃圾回收器专心工作,找出来存活对象,回收掉垃圾对象
一旦垃圾回收全部完毕之后,也就是存活对象都进入了Survivor区域,然后Eden区都清空了,那么Young GC执行完毕,此时系统恢复 工作,继续在Eden区里创建对象。
下一次如果Eden区满了,就会再次触发Young GC,把Eden区和S0区里的存活对象转移到S1区里去,然后直接清空掉Eden区和S0区 中的垃圾对象
当然这个过程中系统是禁止运行的,处于Stop the World状态
负责Young GC的垃圾回收器有很多种,但是常用的就是ParNew垃圾回收器,他的核心执行原理就如上所述,只不过他运行的时候是 基于多线程并发执行垃圾回收的,
1、对象在年轻代里躲过15次垃圾回收,年龄太大了,进入老年代
2、对象太大了,超过了一定的阈值,直接进入老年代,不走年轻代
3、一次Young GC过后存活对象太多了,导致Survivor区域放不下了,这批对象会进入老年代
4、可能几次Young GC过后,Surviovr区域中的对象占用了超过50%的内存,此时会判断如果年龄1+年龄2+年龄N的对象总和超过 了Survivor区域的50%,此时年龄N以及之上的对象都进入老年代,这是动态年龄判定规则
上面4个条件就是最常见的对象进入老年代的情况,那种长期存活的躲过15次Young GC的对象毕竟是少数的,大对象一般在特殊情况 下会有,对于那种加载大量数据长时间处理以及高并发的场景,很容易导致Young GC后存活对象过多的。
1、老年代自身可以设置一个阈值,有一个JVM参数可以控制,一旦老年代内存使用达到这个阈值,就会触发Full GC,一般建议调节大一 些,比如92%
2、在执行Young GC之前,如果判断发现老年代可用空间小于了历次Young GC后升入老年代的平均对象大小的话,那么就会在Young GC之前触发Full GC,先回收掉老年代一批对象,然后再执行Young GC。
3、如果Young GC过后的存活对象太多,Survivor区域放不下,就要放入老年代,要是此时老年代也放不下,就会触发Full GC,回收老年 代一批对象,再把这些年轻代的存活对象放入老年代中
正常情况下的系统的ygc的频率
一般在几分钟一次Young GC,或者几十分钟一次Young GC,一次耗时在几毫秒到 几十毫秒的样子,都是正常的。
正常情况下的系统的full gc的频率
正常的Full GC频率在几十分钟一次,或者几个小时一次,这个范围内都是正常的,一次耗时应该在几百毫秒的样子。 所以大家如果观察自己线上系统就是这个性能表现,基本上问题都不太大。 当然,实际线上系统很多时候回遇到一些JVM性能问题,就是Full GC过于频繁,每次还耗时很多的情况,此时就需要一些优化了。
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
加入交流群
请使用微信扫一扫!