自制脚本语言[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结束之后, 恢复字节码的执行。

线程同步点的添加位置可以是函数开始执行,或者执行结束, 循环开始的时候等。

更优化的方案可以是 使用异步的方式标记垃圾对象, 这样的话, 就会减少暂停的总时间。

0%