JVM基础 -> JVM有哪些垃圾回收算法?

JVM有哪些垃圾回收算法?

  1. 可达性分析法
  2. 标记清除算法
  3. 拷⻉算法
  4. 标记压缩算法
  5. 分代收集算法
垃圾回收会经历两个阶段: 标记可回收对象阶段 -> 可达性分析法 垃圾清除阶段 -> 标记-清除算法 标记-拷⻉算法 标记-压缩算法 分代收集算法

标记可回收对象阶段

    标记可回收对象阶段使用的算法是可达性分析法 可达性分析法: 从 GC Roots 开始向下搜索,搜索所⾛过的路径称为引⽤链。当⼀个对象到 GC Roots 没有任何引⽤链相连时,则证明此对象是不可⽤的,那么虚拟机就判断是可回收对象。 可达性分析法是垃圾回收算法的前提,是非常重要的 因为垃圾回收算法主要考察的是清除垃圾阶段时使用的算法 所以可达性分析法可以查看我都这篇博客

垃圾清除阶段

这个阶段有多个算法,会在不同的情况下选择合适的算法执行 ,这个怎么去选择合适的算法叫分代收集算法

我们会将分代收集算法放到最后去讲,它集合了所有垃圾回收算法

虚拟机都是使用这个分代收集算法的

MarkSweep 标记-清除算法:他是最先出现的垃圾回收算法,有着一些考虑不周的情况,存在一些bug
    算法在标记阶段使用可达性分析法 这种算法是很简单的逻辑,就是把经过可达性分析法之后,已经确定为垃圾的对象都删除。 他是最先出现的垃圾回收算法,有着一些考虑不周的情况,存在一些bug 会产⽣⼤量的内存碎⽚,清除之后内存会很散乱 所以有必要其他算法来修复这个bug 如下图
Copying 标记-复制算法:为了解决标记清除算法的内存碎⽚问题,产⽣了拷⻉算法,JVM的新生代都用的拷⻉算法。
    算法在标记阶段使用可达性分析法 拷⻉算法将内存分为⼤⼩相等的两半,每次只使⽤其中⼀半。 垃圾回收时,将当前这⼀块的存活对象全部复制到另⼀半,然后当前这⼀半内存就可以直接清除。 这种算法没有内存碎⽚,但是他的问题就在于浪费空间。 ⽽且,他的效率跟存货对象的个数有关。 如下图
MarkCompack 标记-整理算法:为了解决标记-复制算法的缺陷,就提出了标记-整理算法,JVM在老年代默认都是标记-整理算法。
    算法在标记阶段使用可达性分析法 在完成标记之后,不是直接清理垃圾内存 ⽽是将存活对象往⼀端移动,然后将端边界以外的所有内存直接清除。 如下图

分代收集算法 -> 我们的重点

分代收集算法: 这个算法并没有新的内容,只是根据对象的存活的时间的长短,将内存分为了新生代和老年代,这样就可以针对不同的区域,采取合适的算法。
    新生代,每次都有大量对象死亡,有老年代作为内存担保,采取标记-复制算法。 新生代的Eden区经过垃圾回收一次后,还存活的对象会被转移到s区 新生代s区中,s0,s1这两个区域,内存都是相同大小 s区经过垃圾回收,对象在s0,s1区域又来回复制倒腾 为什么说有老年代作为内存担保? 因为当新生代来回复制对象,内存超了的时候,要么自适应调整新生代内存,要么直接进入老年代 老年代,对象存活时间长,采用标记-整理,或者标记-清除算法都可。 具体使用哪种算法是需要判断老年代用的哪种垃圾回收器来决定的 CMS垃圾回收器 : 主要标记清除算法 其他垃圾回收器: 标记整理算法 当垃圾达到阈值(空间担保值),一定以及必定会触发FullGC FullGC 不管你是什么回收器,他是垃圾回收的最后尊严,成败在此一举 无论如何怎么整理,怎么垃圾回收,内存都不够了,就说明必须要进行JVM调优了 单纯的垃圾回收已经不顶用了
经验分享 程序员 微信小程序 职场和发展