在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
lua在5.2版本为我们带来了分代GC(分代GC的优点,自己查编译原理去),默认不开启的,默认使用的还是增量GC。 简单描述下lua的分代GC:分代(非增量),而且也只分两代,并不是我们大家常听说的三代。为什么只分两代呢,原因很简单,它只是巧妙的利用了目前已经实现的增量GC机制。 它与 增量GC 的最大差别在于,增量GC 的 sweep 阶段会处理整个链表的对象,并标记为 currrent white (或者称为 翻转白色),而 分代GC 仅仅只处理链表前端的新对象,并标记为old。
基础:lua的对象链表为单向链表,新对象插入链表最前面;对象从创建时就插入 allgc,GC运行时,对象也会被放入 gray、grayagain。(为了简化,这里不考虑弱表 weak table、可析构对象 finalizer 的处理) 1 新GC周期开始,lua对象链上所有对象都是标记为 old 的对象; 虚拟机运行阶段:2 有新对象创建,插入对象链的最前端。 3 如果新对象被 old 对象所引用,Write Barrier 自动将此新对象插入 gray 链——unscan list(如果old对象是容器——table,则将 old 对象放入grayagain 链——rescan list) 2、3步骤反复执行直至满足触发条件,虚拟机停止,GC开始工作 GC运行阶段:4 遍历 gray 链,作标记工作(propagate) 5 遍历 grayagain 链,作标记工作(propagate) 至此GC的 propagate 阶段完成 6 清扫新对象链中新对象(从 allgc 链开始,至第一个标记为 old 对象止):释放的不可达对象内存;可达对象标记为 old GC工作结束。流程又从1开始
下表为 global_State 中 GC 相关的变量 /* ** `global state', shared by all threads of this state */ typedef struct global_State { //新分配对象颜色 lu_byte currentwhite; //GC对象链 GCObject *allgc; /* list of all collectable objects */ // 待扫描对象链 unscan list GCObject *gray; /* list of gray objects */ // 需再次扫描对象链 rescan list GCObject *grayagain; /* list of objects to be traversed atomically */ //控制参数 int gcpause; /* size of pause between successive GCs */ int gcmajorinc; /* how much to wait for a major GC (only in gen. mode) */ int gcstepmul; /* GC `granularity' */ } global_State;
分代GC 可以参考lua邮件讨论 Generational GC (was Re: A review of changes between 5.1 and 5.2-work3) 如果对 lua 5.1 的GC的实现细节感兴趣,可以参考云风针对 lua 5.1.4 的 Lua GC 的源码剖析 |
请发表评论