前言
标记清除算法(Mark-Sweep)是一种非常基础和常见的垃圾收集算法,该算法被J.McCarthy等人在1960年提出并成功的发明并应用于Lisp语言。
涉及概念
先来了解一下mutator
和collector
。这2个名词经常在垃圾收集算法中出现。
collector
指的就是垃圾收集器。
mutator
是指除了垃圾收集器之外的部分,比如说我们的应用程序本身。
mutator的职责一般是NEW(分配内存)、READ(从内存中读取内容)、WRITE(将内容写入内存),而collector则就是回收不在使用的内存来供mutator进行NEW操作的使用。
算法原理
标记清除算法将垃圾回收分为2个阶段,标记阶段和清除阶段。在标记阶段collector从mutator根对象开始进行遍历,对从mutator根对象可以访问到的对象都打上一个标识,一般是
在对象的header中,将其记录为可达对象。而在清除阶段,collector对堆内存(heap memory)从头到尾进行线性遍历,如果发现某个对象没有被标记为可达对象,通过读取对象的header
信息,将其回收。一种可行的实现是,在标记阶段首先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象。然后在清除阶段清除所有未被标记的对象。
存在问题
标记清除算法最大的问题是存在大量的空间碎片,因为回收后的空间是不连续的。在对象的堆空间分配过程中,尤其是大对象的内存分配,不连续的内存空间的工作效率要低于连续的空间。