JVM-垃圾收集--垃圾收集算法

2021-11-11  本文已影响0人  bit_拳倾天下

0. 分代收集

当前大多数商业虚拟机的垃圾收集器都遵循“分代收集”。就是针对不同的内存区域使用不同的数计算法。但是已经有能够全区域收集不分代的收集器了。
未来会不会不分代的虚拟机主导呢,真是的,@_@学习的速度赶不上技术发展的速度。。。

以下内容忽略标记算法,只针对收集。

1. 标记-清除算法

他是最早、最基础的收集算法,分为两个阶段:标记清除
就是第一阶段先标记需要回收的对象(或者不需要回收的对象),然后由第二阶段统一回收。

缺点:1. 随着对象增多,效率降低;2. 清除过后遗留空间碎片

2. 标记-复制算法

将内存一分为二(暂称 A,B),对象存在其中一个区域 A 中,当垃圾收集时,将 A 区的存活对象复制到 B 区(依次贴合),然后把 A 区清空。

优点:

  1. 分配内存只需按顺序分配即可,实现简单、运行高效;
  2. 没有空间碎片;
  3. 只有少数存活对象时,复制开销小(多数对象都是“朝生夕死”,所以很适合新生代)

缺点:

  1. 总是有一半空间需要空闲着,空间浪费严重
  2. 存活对象多的时候,复制成本较大

3. 标记-整理算法

× 本来一直以为,这个算法是 标记、清除、整理三个阶段。原来根本是这么回事儿。。。×

应该是标记移动清除三个阶段。
第一阶段标记,和“标记-清除算法”一样;
第二阶段,是将所有存活对象向着内存的一端移动(标记-清除算法是没有移动的),存活对象都堆在一起之后,进行下一阶段;
第三阶段,将存活对象边界以外的内存清除掉。

优点:

  1. 没有空间碎片,分配内存方便

缺点:

  1. 每次都要移动所有存活对象,负担极大
  2. 需要暂停用户线程,Stop The World

标记-整理 VS 标记-清除
标记-整理算法,在回收过程中,需要移动对象,更复杂,而且需要较长停顿时间,但是分配内存会更方便。但是从程序整体吞吐量看,它比“标记-清除算法”划算,也就是说它侧重整体吞吐量。Parallel Scavenge 收集器才用的就是这种算法。
标记-清除算法,相反的,不需要移动对象,回收相对简单,停顿时间更短甚至不需要停顿,延迟低。但是由于产生空间碎片,使得分配内存更加复杂,吞吐量下降。所以它侧重的是延迟。CMS 收集器使用的是这种算法。

所以,还没有完美的 GC 算法,垃圾收集器根据各自的侧重点选择“标记-整理”还是“标记-清除”,还有的是混合的。CMS 收集器在碎片不多的时候采用 “标记-清除”,碎片过多就会采用 “标记-整理”。

上一篇下一篇

猜你喜欢

热点阅读