JVM内存溢出(五)之新生代老年代

一、年轻代

也叫新生代,顾名思义,主要是用来存放新生的对象。新生代又细分为 Eden区、SurvivorFrom区、SurvivorTo区。

如果新生对象在Eden区无法分配空间时,此时发生YoungGC。发生YoungGC,对象会从Eden区进入Survivor区,如果Survivor区放不下从Eden区过来的对象时,此时会使用分配担保机制将对象直接移动到老年。

在YoungGC开始的时候,对象只会存在于Eden区和Survivor from区,Survivor to区是空的。

YoungGC操作后,Eden区如果仍然存活(判断的标准是被引用了,通过GC root进行可达性判断)的对象,将会被移到Survivor To区。而From区中,对象在Survivor区中每熬过一次Minor GC,年龄就会+1岁,当年龄达到一定值(年龄阈值,默认是15,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,否则对象会被复制到“To”区。经过这次YoungGC后,Eden区和From区已经被清空,所有对象都在to区连续存储

为什么有 From和To,2块区域?这就要说到新生代YoungGC的算法了:复制算法,把内存区域分为两块,每次使用一块,GC的时候把一块中的内容移动到另一块中,原始内存中的对象就可以被回收了,优点是避免内存碎片

二、老年代

随着YoungGC的持续进行,老年代中对象也会持续增长,导致老年代的空间也会不够用,最终会执行Old GC(Old GC 的速度比 YoungGC 慢很多很多,据说10倍左右)。Old GC使用的算法是:标记清除(回收)算法或者标记压缩算法。

标记清除(回收)

  1. 首先会从GC Roots进行遍历,把可达对象(存过的对象)打标记                                  

  2. 再从GC Roots二次遍历,将没有被打上标记的对象清除掉。

 优点:

      老年代对象一般是比较稳定的,相比复制算法,不需要复制大量对象。之所以将所有对象扫描2次,看似比较消耗时间,其实不然,是节省了时间。举个栗子,数组 1,2,3,4,5,6。删除2,3,4,如果每次删除一个数字,那么5,6要移动3次,如果删除1次,那么5,6只需移动1次。

缺点:

这种方式需要中断其他线程(STW),相比复制算法,可能产生内存碎片。

标记压缩:和标记清除算法基本相同,不同的就是,在清除完成之后,会把存活的对象向内存的一边进行压缩,这样就可以解决内存碎片问题。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值