# 垃圾回收器如何工作

#### 关于效率(P89-90)

在以前使用过的程序语言中，在堆上分配对象的代价十分高昂。然而，垃圾回收器对于提高对象的创建速度，却有明显的效果。

垃圾回收站工作时，将一面回收空间，一面使堆中的对象紧凑排列，这样“堆指针”就可以很容易移动到更靠近传送带的开始处，也就尽量避免了页面错误。通过垃圾回收器对对象重新排列，实现了一种高速的、有无限空间可供分配的堆模型。

(页面错误，即访问了不存在的内存空间。)

在堆栈中，堆栈指针向下移动，则分配新的内存，向上移动则释放那些内存。这是仅次于寄存器的快速有效的分配存储的方法。(P22)

#### 可达性分析算法(P90)

对任何"活"的对象，一定能最终追溯到其存活在堆栈或静态存储区之中的引用。这个引用链条可能会穿过数个对象层次。由此，如果从堆栈和静态存储区开始，遍历所有的引用，就能找到“活”的对象。对于发现的每个引用，必须追踪它所引用的对象，然后是此对象包含的所有引用，如此反复进行，直到“根源于堆栈和静态存储区的引用”所形成的网络全部被访问为止。

#### 复制(P91)

在Thinking in Java这本书中(基于Java5)讨论的虚拟机，内存分配较大的“块”为单位。如果对象较大，它会占用单独的块。

严格来说，“停止-复制”要求在释放旧有对象之前，必须先把所有存活对象从旧堆复制到新堆，这将导致大量内存复制行为。有了块之后，垃圾回收器在回收的时候就可以往废弃的块里拷贝对象了。

每个块都用相应的代数来记录它是否还存活。通常，如果块在某处被引用，其代数会增加；垃圾回收器将对上次回收动作之后新分配的块进行整理，这对处理大量短命的临时对象很有帮助。垃圾回收器会定期进行完整的清理动作——大型对象仍然不会被复制(只是其代数会增加)，内含小型对象的那些块则被复制并整理。
