JVM - 垃圾回收算法概述

本文深入解析了五种垃圾回收算法的工作原理及应用场景:标记清除法可能导致内存碎片;复制算法适用于对象朝生夕死的新生代;标记压缩法解决了内存碎片问题;分代算法结合使用复制算法和标记压缩/清除法;分区算法则通过将堆空间细分为多个小区间来提高GC效率。

既然选择了远方,即使天寒地冻,路遥马亡,我本就一无所有,又有何惧。

标记清除法

标记清除算法工作分为 2 个阶段。
第一个阶段,先根据 GC Root 标记 可达对象
第二阶段,将不可达对象,直接清除。

算法缺点:会产生大量的内存碎片

工作原理如下图所示:
在这里插入图片描述

复制算法

复制算法思想:

  1. 将内存一分为二,每次只使用其中一块。
  2. 发生垃圾回收时,将存活的对象复制到另一块未使用的内存
  3. 清空使用的内存块中的对象,两者角色互换,完成垃圾回收。

复制算法,用于新生代。java 借鉴复制算法,将新生代内存划分为 eden、from、to。默认比例为 8:1:1eden, from 存活的对象会被放入 to 中,eden, from 不可达对象会被清空。清空后, from、to 角色互换

算法前提:新生代对象朝生夕死

工作原理如下图所示:
在这里插入图片描述

标记压缩法

标记压缩法思想:

  1. GC Root 可达性分析 标记可达对象
  2. 将可达对象统一放至内存一端
  3. 清理边界外的空间

标记压缩不会产生内存碎片

工作原理如下图所示:
在这里插入图片描述

分代算法

JVM 将对象分为新生代和老年代。
新生代使用复制算法回收垃圾;老年代使用标记压缩或标记清除回收垃圾。

新生代对象大多朝生夕死,正常来说 ygc 频率高,速度快。如果 老年代对象引用了新生代对象,那么就需要扫描老年代对象。因此会造成 ygc 效率低下,需要全堆扫描。
JVM 引入 卡表(card table)数据结构 来解决 老年代对象引用新生代对象,造成 ygc 效率低下 问题。

卡表

JVM 通过卡表,记录老年代指向新生代的引用。
卡表为比特位数组,每个比特位可以用于表示老年代某一区域中所有对象是否持有新生代引用。0 表示没有持有,1表示持有。在 GC Root 扫描时,只需扫描卡表位为 1 的老年代空间即可,避免全堆扫描,提升了 ygc 效率。
在这里插入图片描述

分区算法

分区算法将整个堆空间分成连续的不同小区间,每一个小区间独立使用,独立回收。分区算法的好处是,可以控制一次 GC 回收的区间,即控制 GC 回收时间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xcUVLOZC-1608564402272)(evernotecid://B58292A4-43F3-4C3E-ACA3-E9C7D829CC18/appyinxiangcom/15559189/ENResource/p3110)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值