JVM老年代垃圾回收Full GC

老年代GC:FullGC 是老年代的GC,在新生代如果说存在的对象或者说新创建 出来的对象由于某些原因需要移动到老年代中,但是老年代中压根就没有这么大的内存空间去容纳这个对象, 那么就会引发一次FullGC,如果在执行完FullGC之后,还是没有办法给这些对象分配内存,那么凉了,该抛出异常了,异常类型就是OutOfMemoryError。

FullGC危害:在发生FULL GC的时候,意味着JVM会安全的暂停所有正在执行的线程(Stop The World),来回收内存空间,在这个时间段内,所有除了回收垃圾的线程外,其他有关JAVA的程序,代码都会静止,反映到系统上,就会出现系统响应大幅度变慢,卡机等状态。

而FullGC使用的是和MinorGC不一样的算法,它使用的是标记清除算法,听名字,挺好理解的,来波图示解析一波。 深入了解JVM一书中的图示是这个样子的,

看名字的话是先标记,然后在删除。这也是也给最最基本的算法。 这个算法就是分两个步骤

•标记(Mark)过程:找到所有的可以访问的对象,做个指定的标记。

•清除(Swep)过程:遍历堆内存,把未标记的对象进行一个回收。

在了解了这个之后,我们还得说一个概念,那就是GC Root,Root我们可以理解成一个根节点就像这个样子

 

上图中的a,b,c,d,就是活着的对象,如果说存在这引用,比如说b引用的a,那么a他就是属于活着的对象。 当我们老年代内存区中的有效的内存空间不够的时候,那么这时候整个世界都要安静下来了(stop the world),这时候就要开始准备进行垃圾回收了。

•标记:遍历所有的GC Roots,然后将所有GC Roots可达的对象标记为存活的对象。就是我们图中所标记的a,b,c,d.•清除:清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。 也就是说,如果内存不够,GC线程就会被触发然后将程序暂停,随后将依旧存活的对象标记一遍,最后再将堆中所有没被标记的对象全部清除掉,接下来便让程序继续恢复运行。 

流程图就想这个样子的 初始下的老年代中的对象状态

 

这时候都是没有被标记的状态,接下来内存不够,GC线程停止,开始进行标记了

 

按照根节点开始遍历 标记的abcdeh都是存活的对象,接下来开始标记。

接下来就是清除数据了,这个就更加的简单了

清楚完成之后还有就是把标记去除掉,可以下次进行标记清除的时候继续清除

这样标记清除就执行完毕了,剩下还有两个要说的地方,

 一是在进行标记清楚算法的时候为什么要让程序停止,(stop the world)。

 二是标记清除算法的优点和缺点又是什么?(Stop the World)

程序停止其实可以理解,因为如果说不停止程序的话,我们在标记完成这个b对象之后,我们new出一个新的对象J,可以从B指向J,也就是说,这时候J应该是被标记的状态,但是实际情况肯定不是,这个对象在B标记完之后,马上都要结束了,我们又new出来一个对象,可想而知,他肯定是没有被标记的,所以在第二阶段进行清除的时候,这个苦命的J将会被清除掉, 那这样肯定是不符合我们的实际情况的。

你想呀这刚刚new出来的对象结果被清除了,忽然变成了空值,那就不符合我们的要求了。所以他会让程序先停止,然后不会再出现这种情况,然后进行开始标记阶段。

 

优缺点

首先我们可以先看缺点,他的缺点非常明显,

•因为他会递归遍历Root,这样的话 Stop the World的时间就比较长了,这样一直让人等待的滋味可不是那么好受。•第二个就是这种清除方式清除出来的内存空间是不连续的,你看这个图

 

死亡的上下分成了2部分,是不连续的,这样给JVM又造成了一种额外的负担,他需要去维持一个内存的空闲列表,如果说我们在这时候去new一个数组,你想想他去找这个连续的内存空间的话,是不是就要困难很多呢?

他的优点也有,

•比如说不会出现循环引用, 我们可以想想 两个类 互相引用,A中newB,B中newA,那这样岂不是a.b=b ,b.a = a ,是吧 ,而标记清除算法在走完了之后,是可以回收a,和b的,因为他是从根元素开始遍历标记,也就是从ab开始,那么单一的a和单一的b就是没有被标记的,所以,这样就避免了循环引用的问题•还有一点感觉没啥区别,都是内存不够的时候才进行的引用。这没啥说的。

标记--整理算法

而因为标记--清除算法会导致内存分配都出现了各种不均匀的空间,这时候就有了另外的一种算法,直接把那些存活的对象标记出来,然后给他怼到内存空间边界,然后剩下的直接全给他清除了。这方法图解看的一清二楚,剩下的都是和标记清除算法一样的,好像没啥解释的,直接上图

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值