Garbage collection

内存管理分自动和手动:

  • C C++手动管理内存
  • jave golang有自动的内存管理系统,有内存分配器和垃圾回收器

主流的垃圾回收算法:

  • 引用计数 - php使用引用计数
  • 追踪式垃圾回收 - golang的三色标记法属于追踪式

Mark & Sweep

标记清除算法

STW:stop the world,需要停止已确定当前的引用关系

Root对象:不需要其他对象就能直接访问的对象,如全局对象,栈中对象的数据,通过root对象能追踪其他存活的对象

追踪式算法
  • stop the world
  • Mark: 通过root对象和root直接访问到的对象,来寻找所有可达的对象进行标记
  • Sweep:对堆中的对象,将已标记的对象标记,所有未标记的对象加入freelist,用于再分配
  • start the world

这种方法内存碎片率高,stop the world基本秒级,go 1.1 全程stw,不可用。

go 1.3 对程序进行分块执行mark和sweep;同时分离mark和sweep,仅在mark阶段stwsweep过程和程序并发执行

1.5版本后使用三色标记法,mark和sweep均并发执行,mark前后需要进行stw进行准备工作

三色标记法

white grey black

垃圾收集器递归扫描root的内存空间。

初始均为white,将root对象加入待扫描队列,加入队列即变为grey,有被引用的也进入队列,那么被扫描的变为黑色。

white:潜在垃圾

black:活跃对象,不需扫描其子对象

grey:活跃对象,需要扫描其子对象

https://zhuanlan.zhihu.com/p/77943973

写屏障和混合屏障都是为了减少stw的时间,让mark sweep可以同程序并发执行

垃圾收集开始时,必须执行的第一个动作是打开写屏障(Write Barrier)。写屏障的目的是允许垃圾收集器在垃圾收集期间维护堆上的数据完整性,因为垃圾收集器和应用程序将并发执行