上一篇: 004-JVM-Java 中使用的标记阶段的算法: 可达性分析算法中 GC Roots 有哪些 juejin.cn/post/690816… 前面我们知道了垃圾,并且有办法找到垃圾,找到之后怎么办呢?干掉 kill 掉吧。
前面我们知道了垃圾,并且有办法找到垃圾,找到之后怎么办呢?干掉 kill 掉吧。释放掉无用对象所占用的内存空间, 以便有足够的可用内存空间为新对象分配内存。
那么这里就单纯讨论一下有那些垃圾回收算法。
标记阶段完成后,就是清楚阶段。吓人
位置不连续 产生碎片
是一种非常基础和常见的垃圾收集算法,该算法被 J.McCarthy 等人在 1960 提出并应用于 Lisp 语言。
没有碎片,浪费空间
为了解决标记 - 清除算法在垃圾收集效率方而的缺陷 M.L.Minsky 于 1963 年发表了著名的论文, “使用双存储区的 Lisp 语言垃圾收集器 CA LISP Garbage CoIIector Algorithm Using SeriaI Secondary Storage 。M.L.Minsky 在该论文中描述的算法被人们称为复制 (copying) 算法, 它也被 M.L.Minsky 本人成功地引入到了 Lisp 语言的一个实现版本中。
没有碎片,效率偏低
复制算法的高效性是建立在存活对象少、垃圾对象多的前提下的。这种情况在新生代经常发生, 但是在老年代, 更常见的情况是大部分对象都是存活对象。如果依然使用复制算法,由于存活对象较多, 复制的成本也将很高。因此, 基于老年代垃圾回收的特性, 需要使用其他的算法。
标记 - 清除算法的确可以应用在老年代中, 但是该算法不仅执行效率低下, 而且在执行完内存回收后还会产生内存碎片, 所以 JVM 的设计者需要在此基础之上进行改进。标记一压缩 (Mark - Compact) 算法由此诞生。
1970 年前后, G.L.SteeIe 、C.J.Chene 和 D.S.Wise 等研究者发布标记 - 压缩算法。在许多现代的垃圾收集器中, 人们都使用了标记 - 压缩算法或其改进版本。
从上面可以看出他们的出现均有其背景,且步步递进,但是现在这三种算法在不同的垃圾回收其中均有选择使用,所以现在市面上均有占用率。后面会针对每一种做展开。