JVM垃圾回收算法及JVM垃圾收集器

1. JVM垃圾回收算法

1.1 标记清除算法

最基础的垃圾回收算法,分为两个阶段,标注和清除。标记阶段通过可达性分析算法标记出所有存活的对象,在清除阶段对所有未标记的对象进行统一回收, 如图:
在这里插入图片描述
缺点: 内存碎片化严重,后续可能发生大对象不能找到可利用空间的问题;其次,两个阶段效率都不高

1.2 标记复制算法

为了解决 Mark-Sweep 算法内存碎片化的缺陷而被提出的算法。按内存容量将内存划分为等大小的两块。
在同一时间只会使用其中一块内存区域来分配对象。在发生GC时,首先通过根可达性分析算法判断存活对象,并且将所有的存活对象移动到另一块未使用的内存区域,最后对于前面的这块使用了的内存区域中的对象统一回收。如图:
在这里插入图片描述
优点:实现简单,内存效率高,不易产生碎片
缺点:可用内存被压缩到了原本的一半,且存活对象增多的话,复制算法的效率会大大降低

1.3 标记整理(压缩)算法

结合了以上两个算法,为了避免缺陷而提出。标记阶段和 Mark-Sweep 算法相同,标记后不是清理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象。如图:

在这里插入图片描述

2. JVM垃圾收集器

2.1 什么是STW

stw 是stop the world的简称,当JVM在进行垃圾回收时,会暂停用户线程,以便正确标记对象的状态是垃圾还是非垃圾,方便后续进行垃圾回收。如果没有STW机制,用户线程与JVM垃圾回收线程同时运行时,会出现,之前被垃圾回收线程标记为非垃圾的对象,等用户线程执行完又变成垃圾了,这样JVM垃圾回收将永远无法停止,因此需要暂停用户线程,将一批标记为垃圾的对象清除后,再让用户线程执行。

2.2 垃圾收集器

常见的垃圾收集器有CMS,G1,ZGC,G1是用的最多的。在JDK1.8及以前,JVM使用分代模型,1.8之后使用分区模型
在这里插入图片描述

2.2.1 UseSerialGC

当用户线程执行到安全点,JVM执行引擎暂停用户线程,开启一个GC线程,对于年轻代,使用标记复制算法进行垃圾收集,对于老年代,采用标记整理算法进行垃圾收集,缺点:GC是单线程,效率低
在这里插入图片描述

2.2.2 UseParNewGC

在这里插入图片描述

2.2.3 UseParallelGC/ UseParallelOldGC

新生代使用 Parallel Scavenge GC 老年代使用 ParallelOld GC
在这里插入图片描述

2.2.4 UseConcMarkSweepGC

使用-XX:UseConcMarkSweepGC, 新生代使用ParNew GC, 老年代使用CMS GC与Serial Old GC的收集器组合,Serial Old 将作为CMS出错后的后备收集器
在这里插入图片描述
CMS并发标记清除的过程:

  • 初始标记
    只将GC root 所直接引用的对象标记出来,其他的对象不管
  • 并发标记
    这个阶段用户线程可以执行,同时,将GC root 可达的所有对象标记出来(一边产生垃圾,一边标记垃圾对象,不严谨)
  • 重新标记
    暂停用户线程,将并发标记阶段错标,漏标的对象重新进行标记
  • 并发清理
    在这里插入图片描述
    注:图片来自https://www.processon.com/view/5dec50d7e4b0e2c298a6bd60?fromnew=1

CMS之所以采用这么复杂的标记清除过程,是为了解决STW时间过长的问题

2.2.5 G1垃圾收集器

分代收集思想: 不管房间有多大,这个房间里面的垃圾都清除掉
分区收集思想: 不管你房间有多大,我把房间分成多个小块,先清理出一块区域给你用,后面再继续清理其他区域,用户不用等太久

在这里插入图片描述

在这里插入图片描述
其他参考:
https://www.processon.com/view/5f7fdf845653bb06eff0a16d?fromnew=1

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值