GC分析
1.从根节点开始遍历GC对象,如果可达,则标记;
2.遍历所有的GC对象,清除没有标记的对象
三色标记法
三色标记法是Lua5.1后的一种三色回收算法
- 白色:在开始时,是所有的对象都为白色,但在遍历完一遍对象后如果还是白色那么将被清楚;
- 灰色:用在分布遍历阶段,如果一直是对象为灰色的话,遍历不会停止
- 黑色:确定对象被引用,将不会被清除;
GC的6种状态
- GCSpause:gc开始阶段,初始化一些属性,将一些跟节点(主线程对象,主线程环境对象,全局对象等)push到灰色链表中。
- GCSpropagate:分步进行扫描,每次从灰色链表pop一个对象,遍历该对象的子对象,例如如果该对象为table,并且value没有设置为week,则会遍历table所有table可达的value,如果value为gc对象且为白色,则会被push到灰色链表中,这一步将一直持续到灰色链表为空的时候。
- GCSatomic:原子操作,因为GCSpropagate是分步的,所以分步过程中可能会有新的对象创建,这时候将再进行一次补充遍历,这遍历是不能被打断的,但因为绝大部分工作被GCSpropagate做了,所以过程会很快。新创建的没有被引用的userdata,如果该userdata自定义了gc元方法,则会加入到全局的userdata链表中,该链表会在最后一步GCSfinalize处理。
- GCSsweepstring:遍历全局字符串hash表,每次遍历一个hash节点,如果hash冲突严重,会在这里影响gc。如果字符串为白色并且没有被设置为固定不释放,则进行释放。
- GCSsweep:遍历所有全局gc对象,每次遍历40个,如果gc对象为白色,将被释放。
- GCSfinalize:遍历GCSatomic生成的userdata链表,如果该userdata还存在gc元方法,调用该元方法,每次处理一个
什么时候会导致gc?
1.luajit中有两个判断是否需要gc的宏,如果需要gc,则会直接进行一次gc的step操作。
2.这两个宏会在各个申请内存的地方进行调用,所以当前申请的内存如果已经达到设置的阈值,则会申请的所有对象都会有gc消耗。