图解Java中的GC(分代收集器)

前面在Java垃圾收集算法中讲过垃圾收集算法中的分代收集器,今天看了一个视频发现里面将的也很不错,所以决定再总结一下。

我们知道,在分代收集算法中堆空间被分为新生代和老年代。因为新生代中对象的存活率比较低,所以一般采用复制算法,老年代的存活率一般比较高,一般使用”标记-清理”或者”标记-整理”算法进行回收。



上面的这个图已经很清楚的将堆的分区展现出来了。


下面我们来看看具体的算法过程。

新创建的对象一般放在新生代的Enden区,如下图所示。



上面对象中,绿色代表的是"存活对象",灰色的代表的是"待回收对象"。当Enden中被使用完的时候,就会发生新生代GC,也就是Minor GC,如下图。



首先会把存活对象复制到Survivor1中。



然后把Enden清空



移动到Survivor1空间后,设置对象年龄(Age)为1


这样第一次GC就完成了。


当Enden区再次被使用完的时候,就会再次进行GC操作


上面Enden和Survivor1中,绿色表示存活对象,回收表示"待回收对象",因为在堆内存使用分配的过程中,也会不断有对象变得引用不可达。


再次GC的过程中,跟上面一样,将Enden区和Survivor1中的存活对象复制到Survivor2中。需要注意的是目前还是处于新生代的GC,因为新生代分为Enden、Survivor1、Survivor2三个区,使用的其实就是复制算法。



接着将Enden和Survivor1进行清空



然后将Enden中复制到Survivor2中的对象年龄设置为1,将Survivor1中复制到Survivor2中的对象年龄加1



这样新生代第二次GC就完成了。当Enden再一次被使用完的时候,就会发生第三次GC操作了。



下面基本重复上面的思路了,首先将Enden和Survivor2中的存活对象复制到Survivor1中。



然后将Enden和Survivor2进行清空



然后将Enden中复制到Survivor1中的对象年龄设置为1,将Survivor2中复制到Survivor1中的对象年龄加1



后面的操作基本都是重复的,那什么时候会进入老年代呢?从上面看到,如果对象在GC过程中没有被回收,那么它的对象年龄(Age)会不断的增加,对象在Survivor区每熬过一个Minor GC,年龄就增加1岁,当它的年龄到达一定的程度(默认为15岁),就会被移动到老年代,这个年龄阀值可以通过-XX:MaxTenuringThreshold设置。



视频链接:Garbage collection in Java, with Animation and discussion of G1 GC


当在Eden区中申请内存空间时,如果Eden区剩余空间不够,则看当前申请的空间是否大于等于Eden总空间的一半,如果大于,则直接在Old中分配,如果小于,则触发Minor GC,触发前首先检查每次Minor GC时复制到Old区的平均大小是否大于Old的剩余空间,如果大于,则再触发Full GC。此次触发GC后仍然会按照这个规则重新检查一次,如果仍然满足,Full GC会再一次触发。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值