自制脚本语言[8.1] GC的简单讨论
目录
本文为想法草稿,并没有真实实践过。
GC 简介
GC就是垃圾回收器, 现代脚本语言基本上都是有GC的, 而现代编程语言中除了c/c++ 之外的其他大多数也都存在GC。
GC的好处:
- 不需要代码编写者关注和管理内存
- 基本上不会出现段错误的情况。
GC的坏处:
- 性能的降低
- 内存占用增大
实现方案考虑
在实现GC的时候, 基本上可以分成两个部分: 垃圾内存识别, 垃圾内存回收。
垃圾内存识别
目前常用的方法可能有两种: 引用计数, 可达性分析。
引用计数的含义是 给每个对象都添加一个引用计数的属性, 当其他对象引用了对象A的时候, A的引用计数就+1。 当引用计数为0的时候就表示对象A是一个垃圾对象, 可以进行回收。
引用计数的好处是:
- 实现简单
引用计数的坏处是:
- 如果垃圾对象中出现了循环引用, 则这一批对象都难以释放。
可达性分析则是分析一个对象是否被GC Roots 引用了, 如果被引用,则说明是活跃对象, 否则是垃圾对象。
GC Roots 可以是下面之一:
- 代码区
- 局部变量表 (程序栈)
- 全局变量表 (包括静态对象)
- 以及其他 。。
垃圾内存回收
简单的实现方法就是暂停所有字节码的执行, 专注于 垃圾对象识别, 识别之后就立即回收。
那么, 在何时暂停呢? 可以考虑添加线程同步点, 步骤如下:
- 添加一个全局标记位 标记是否要进行GC。
- 如果需要进行GC, 那么在线程同步点的地方, 线程将暂停, 不会执行后面的字节码。
- 当所有线程都到达了同步点之后, 就开始GC操作, 等GC结束之后, 恢复字节码的执行。
线程同步点的添加位置可以是函数开始执行,或者执行结束, 循环开始的时候等。
更优化的方案可以是 使用异步的方式标记垃圾对象, 这样的话, 就会减少暂停的总时间。