0. GC 前置知识
阅读《垃圾回收的算法与实现》时记录的一些笔记。
-
对象
在GC的世界中,对象表示的是"通过应用程序利用的数据的集合"
-
头
我们将对象中保存对象本身信息的部分称为头。头主要含有一下信息
- 对象的大小
- 对象的种类
-
域
我们把对象使用者在对象中可访问的部分称为“域”
域的数据类型大致分为以下2中:
- 指针
- 非指针
-
指针
GC是根据对象的指针指向去搜索其他对象的。另一方面,GC对非指针不进行任何操作。
- GC在一般情况下无法严谨地判断寄存器和调用栈中的值是指针还是非指针。
-
mutator
非GC的部分(例如说应用自身的代码)是mutator,换言之它的实体就是"应用程序"
-
mutator实际进行的操作有以下两种。
- 生成对象
- 更新指针
-
-
collector
GC自身就是collector
-
分配
分配指的是在内存空间中分配对象。当mutator需要新对象时,就会向分配器)(allocator)申请一个大小合适的空间。分配器则在堆的可用空间中找寻满足要求的空间返回mutator
-
堆
堆指的是用于动态(也就是执行程序时)存放对象的内存空间。当mutator申请存放对象时,所需的内存空间就会从这个堆中被分配给mutator。
为了简化问题
- 我们把
$heap_start
定为指向堆首地址的指针。 - 把
$heap_end
定为指向堆末尾下一个地址的指针。 - 堆大小固定为常量
HEAP_SIZE
$heap_end = $heap_start + HEAP_SIZE
- 我们把
-
活动对象/非活动对象
我们将分配到内存空间中(也就是堆)的对象里能通过mutator引用的对象称为活动对象,
反之,把分配到堆中那些不能通过程序引用的对象称为“非活动对象”。- 非活动对象无法直接转为活动对象,必须要经过销毁重分配的过程。
-
分块
分块(chunk) 在GC的世界里指的是为利用对象而事先准备出来的空间。
-
根
在GC的世界里,根是指向对象的指针的"起点"部分。
GC把可以直接或间接从全局变量空间中引用的对象视为活动对象。与全局变量相同,我们也可以通过mutator直接引用调用栈(call stack)和寄存器。也就是说,调用栈、寄存器以及全局变量空间都是根。

-
评价标准
评价GC算法的性能时,一般采用以下4个标准。
-
吞吐量
吞吐量(throughput)指的是“在单位时间内的处理能力"
-
最大暂停时间
最大暂停时间指的是“因执行GC而暂停执行mutator的最长时间”
-
堆使用效率
影响使用效率的因素有两个
- 头的大小,头一般是越小越好。
- 堆的用法,可用的堆越大,GC运行越快;相反,越想有效地利用有限的堆,GC花费的时间就越长。
-
访问的局部性
具有引用引用关系的对象之间通常很可能存在连续访问的情况。被称为“访问的局部性”。
考虑到访问的局部性,把具有引用关系的对象安排在堆中较近的位置,就能提高在缓存中土去到想利用的数据的概率,令mutator高速运行。
-