java垃圾回收算法_Java的垃圾回收算法

Java里面根据对象的存活周期,把内存分成多个区域,不同区域使用不同的回收算法回收对象

回收类型

Java把堆分成了新生代和老年代 经过分代处理之后 垃圾回收被分成了如下两个部分新生代回收(Minor GC ,又叫Yong GC)

老年的回收(major gc)因为成为

是整个堆的回收,也称full gc

一般情况下一次老年代的回收会伴随着清理整个堆 所以可以理解为老年代回收约等于清理整个堆

对象的分配过程

对象在创建的时候会先分配到 eden,等eden满之后就会触发垃圾回收,这次的回收是把 eden 里面的对象拷贝到存活区里面的 from survival 或者 to survival 这两个区域,下次就是从from拷贝到to里边,再到下一次呢,会把to survival 复制到 from survival,如此周而复始。这个过程呢,就使用了复制算法,这也是新生代,为什么有两个survival的原因,因为复制算法需要把一个内存分为两部分。在新生代如果对象每经历一次垃圾回收的话,它的年龄就会增加1,当对象的年龄增加到阈值(默认 15 ),就会晋升到老年代,老年代里边的对象的存活周期一般是比较高的,老年代里的对象一般会使用标记清除或标记整理来进行回收。

对象分配的例外过程

上面提到的这个对象回收的过程是一个典型的回收过程,实际情况是存在例外的新建对象不一定分配到 eden,可能直接进入老年代当对象大于 XX:PretenureSizeThreshold (默认为0 ) 就会直接分配到老年代,但是这个参数默认情况下是 0,所以一般是直接分配到eden区;

新生代的空间根本不够,如果你创建了一个非常大的数组的对象,那有可能会直接分配到老年代。

这里你可能有疑问了,为什么要让这个对象可以直接进入老年代呢?我们知道新生代都是采用复制算法进行垃圾回收的,如果对象非常大的话,这样会造成eden和两个survival之间大量的内存拷贝,这是我们不想看到的情况,所以你既然非常的庞大,那么直接就去下老年代吧,我这新生代小庙容不下您

动态年龄:虚拟机有一个动态年龄的概念,什么意思呢?如果survival空间中所有相同年龄对象大小的总和大于survival空间的一半,那么年龄大于等于该年龄的对象,就可以直接进入老年代。

触发垃圾回收的条件

新生代的eden空间不足

老年代老年代空间不足老年的空间不足,又分为老年的空间真的不足了,和老年代中的的空间碎片太多也没有,至于没有连续的空间去分配内存

圆空间不足

要晋升到老年代的对象所占用的空间大于老年的剩余空间

调用了system.gc

简单小结一下,分代回收算法是根据对象的生命周期把内存做了分代,然后分配对象的时候,把不同生命周期对象分配到不同的代里, 新生代里的对象存活周期一般都比较短,每次gc 的时候,会有大量的对象死去, 98%以上的对象都会很快消亡,所以新生代可以使用复制算法,而老年代的对象存活周期一般比较长,所以使用了标记整理或标记清楚的垃圾回收算法

分代的好处更有效的清楚不再需要的对象。

提升了垃圾回收的效率,如果不做分代处理的话,需要扫描整个堆里面的对象,那么现在只需要分代去扫描。

分袋收集收集调优原则合理设置survival区域的大小,避免内存浪费。

尽量让gc发生在新生代减少 full gc的发生。

全文完。参考资料 《深入理解 Java虚拟机》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值