GC的4种算法

GC的4种算法

复制算法

我们先来看一张原理图
在这里插入图片描述

  • 明确发生的作用域

    年轻代中采用的Minor GC 这种GC算法采用的复制算法

  • 过程分析

当GC开始后 对象只会存在于Eden和From区 而To区是空的 紧接着进行GC Eden中所有存活的对象和From中没有到阈值的对象被复制到To区 这个时候Eden和From区的对象已经被清空了 这个时候From和To区会交换他们的角色 也就是新的To就是上次的From 新的From就是上次的To区 这样的目的始终保证To区是空的 Minor GC会一直进行这样的过程 直到To区被填满 会将所有对象移动到老年代

  • 上图形象理解

Eden中的红色代表Eden中的存活对象 From区中的红色代表From区中的存活对象 复制就是把Eden中的红色对象和From中的红色对象拿到To去中 然后谁空谁是To 完成了To和From的角色交换 始终保持To区是空的

  • 抽象出一个转移过程

一旦发生GC 就是将10%的from和80%的eden中存活的对象转移到to去当中 接下来将90%除to区之外的空间全部释放

  • 劣势

适用于存活率不高的情况 如果存活率很高 我们就要把所有的对象都复制一遍

浪费了内存

标记清除

同样我们先看原理图
在这里插入图片描述

  • 明确发生的作用域

标记清除算法发生在老年代

  • 思想

先将有效指引的对象标记,再清除未标记的对象

  • 优点

相比复制算法来说不浪费内存

  • 缺点

效率低(因为要遍历扫描2次),会产生内存碎片(清除后的内存是不连续的)

标记整理(压缩)

为了解决Copying算法的缺陷,充分利用内存空间,提出了Mark-Compact算法。该算法标记阶段和Mark-Sweep一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存。
在这里插入图片描述

  • 位置:发生在JVM虚拟机的老年代中
  • 思想:将标记的对象连续的放到一端,将未标记的对象放到另一端,然后将未标记的对象清除
  • 优点:与标记清除算法比,内存是连续的,与复制算法比不浪费内存
  • 缺点:效率比复制算法低,需要多维持一个链表,用于使幸存的对象连续

引用计数法

给对象添加一个引用计数器,当有一个地方引用它时,计数器值就加1;当引用失效时,计数器就减1;任何时候计数器都为0的对象就是不可能再被使用的

小总结

  • 分代收集算法

    一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或“标记-整理”算法来进行回收。

    本文参考:https://blog.csdn.net/weixin_41047933/article/details/86009018

发布了39 篇原创文章 · 获赞 19 · 访问量 1460

猜你喜欢

转载自blog.csdn.net/weixin_44222272/article/details/105665398