1、垃圾收集器的基本知识
所谓垃圾收集,就是显示的分配堆块而不去显示的释放。由垃圾收集器对已分配但是程序不再需要的堆块进行释放。
1. 节点
该图的节点被分成一组根节点(root node)和一组堆节点(heap node)。
- 堆节点
每个堆节点对应堆中的一个已分配块。 有向边p–>q意味着块p中的某个位置指向块q中的某个位置。 - 根节点
根节点对应于这样一种不在堆中的位置, 它们中包含指向堆中的指针。 这些位置可以是寄存器、栈里的变量, 或者是虚拟内存中读写数据区域内的全局变量。
2. 可达与不可达
当存在一条从任意根节点出发并到达p的有向路径时, 我们说节点p是可达的(reachable)。在任何时刻, 不可达节点对应垃圾, 是不能被应用再次使用的。垃圾收集器的角色是维护可达图的某种表示, 并通过释放不可达节点且将它们返回给空闲链表,来定期地回收它们。
3. 精确的垃圾回收器和保守的垃圾回收器
像ML和Java 这样的语言的垃圾收集器, 对应用如何创建和使用指针有很严格的控
制, 能够维护可达图的一种精确的表示, 因此也就能够回收所有垃圾。
C++这样的语言的收集器通常不能维持可达图的精确表示。这样的收集器也叫做保守的
垃圾收集器。保守的垃圾回收器会将部分不可达的节点视为可达的。
2、Mark & Sweep垃圾收集器
1. 标记阶段
标记出所有根节点可达的和已分配的后继。
2. 清除阶段
释放所有未被标记的已分配块。
初始情况下, 图9-52 中的堆由六个已分配块组成, 其中每个块都是未分配的。第3块包含一个指向第1块的指针。第4块包含指向第3块和第6块的指针。根指向第4块。在标记阶段之后, 第1块、第3块、第4块和第6块被做了标记, 因为它们是从根节点可达的。第2块和第5块是未标记的, 因为它们是不可达的。在清除阶段之后, 这两个不可达块被回收到空闲链表。