这篇文章让我们收尾GC的具体后续操作。转载请标明出处:http://www.cnblogs.com/zblade/
3、GC的扫描阶段 GCSpropagate
只要处于这个阶段,就会分2种情况执行,一个是propagatemark,一个是atomic,让我们分别看其实现过程。
首先看处于灰色链表中一直都有对象的情况,在这步操作当中,是可以分步操作的,整个GC的分步操作,就是在这一步操作中,在每次扫描后,都会返回本次扫描标记的对象的大小之和,再下一个分步执行的时候再继续执行,而一旦进入atomic函数中,就需要一次性的执行,不能再分步执行了。
来看propagatemark函数是如何实现的:
对于table,如果该表是weak表,则退回到灰色状态,否则遍历表的数组和散列表部分进行标记,详见traversetable函数;
对于func,traverseclosure主要对func中的upval进行标记;
对于thread, 则将其移植到grayagain中,放在atomic中进行处理;
对于proto,对其中的字符串、upvalue、局部变量等进行遍历标记;
注意,这儿没有处理string\udata类型数据,这是放在其他部分进行的,不需要进行相关的标记;
 
4、GC 扫描阶段的barrier操作
由于采用分步式增量扫描标记算法,所以会出现在分步操作过程中,新增加的对象与被扫描过的对象之间有引用关系的变化,未来确保黑色对象引用的对象中有白色对象,lua提供了两种操作设计:
1)标记过程向前走一步 luaC_barrierf
如果新建对象是白色,而它被一个黑色对象引用了,那么将这个新建对象颜色从白色变为灰色;
2)标记过程向后走一步 luaC_barrierback
类似于上,此时将引用的它的黑色对象的颜色从黑色变为灰色,使得其重新被扫描一次
(或许你看出截图颜色变了,是的,回家了,又是新的编辑器了~)
从define可以看出,只有table需要进行luaC_barrierback,这是由于table本身设计,就是一个table可能会对应N个key或者value,这样如果新增一个key/value,如果将其置为灰色,然后将其加入gray链表中,这样多个添加会带来较大的性能。
采用向后,就是将该table对象退回到gray状态,这样添加多个,其实质都是只改变该table一次,注意这个gray不是改为gray链中,而是将该table加入到grayagain链中,在扫描完gray链后再扫描grayagain链即可。参考源码即可:
对比向前比较简单了:直接调用reallymarkoject
 
5、GC的atomic操作
当gray链表中对象都标记完成后,会执行一次atomic操作,注意这个操作是不能被打断的,所以叫原子操作,参考源码:
首先处理上一篇文章中提到的对open状态的upvalues,然后处理一次gray链表;
然后处理整个弱表,将lua_State指针指向meta表,然后处理一次gray链表
然后处理grayagain链表,类似于上
然后处理udata,其处理函数为luaC_separateudata:
注释很详细,注意放到tmudata链表中后,是在后续操作再集中处理一次;
处理完基本的几个数据后,atomic会把白色类型切换到下一个GC操作的白色类型,然后修改状态到回收阶段CGSsweepstring, 这儿对sweepstrgc进行了赋初值,是为了下面的字符串定位。
 
6、GC的回收阶段 GCSsweepstring/GCSsweep
首先进入的回收阶段是对字符串的处理
虽然是case,但是其实质是一个循环,每次取出散列表中的一个字符串链表,进行一次遍历回收,sweepwholelist最终会调用到sweeplist,等一下给出源码。
当处理完所有的字符串后,切换到GCSsweep状态:
关键操作是sweeplist,参看其源码:
代码中也对前面说的多色标记中的两种白色的作用做了讲解,otherwhite就是本次不可回收的白色,如果处理的对象的白色就是otherwhite,是不会被回收的
 
7、结束阶段 GCSfinalize
这是整个GC的最后阶段了,来看看其操作的源码:
首先处理,是否有前面提到的tmudata链表, 其操作函数为GCTM:
注意,udata本身有GC方法,未来确保其GC方法的调用,实在这次GC中调用G方法,但是这个udata本身,是在下一次的GC中才会被回收的。udata的GC调用则是在fasttm中调用TM_GC来实现。
初看也会迷糊怎么循环的,其实结合上面的case中的 if(g->tmudata)可以理解,为什么每次GCTM都会执行 g->tmudata的移动赋值操作。
 
最终万事大吉,本次GC流程走完,设置到GCSpause状态,等待下一次GC调用。
 
8、GC的进度控制
其实GC的调用,可以分为两种,一种是自动调用,一个是手动调用
自动调用函数: luaC_checkGC
一般不希望自动GC,可以采用setthreshold,将GCthreshold的值设置为非常大,这样不回自动触发GC
手动调用,则设置GC的相关参数 setthreshold:
estimate是对当前内存使用量的一个预估值,gcpause是一个百分比,通过lua_gc可以设置,另一个gc进度的参数是gcstepmul,其主要影响singlestep函数的调用次数,具体原因参看源码:
整个流程都在注释中讲解了,其中关键是lim的设置,然后不断的调用singlestep, 然后处理GC状态即可,注意setthreshold是设置的两次GC之间的时间间隔。由于修改了threshold,对于关闭自动GC的情况,需要再次重新设置关闭自动GC一次。
 
9、总结
对于lua的GC的原理的探究就到这儿,熟悉一门语言的GC流程后,同理去推导理解其他语言的GC会有很大帮助,同时也可以在平时使用lua的时候,对于GC的一些操作更加知其所以然。大家共勉!
 

深入探究Lua的GC算法(下)-《Lua设计与实现》的更多相关文章

  1. 深入探究Lua的GC算法(上)-《Lua设计与实现》

    对于内存的管理,是程序在应用的时候的必需知识点,<Lua设计与实现>中对Lua语言的GC原理做了一个详细的讲解,云风的blog也对其进行了详尽的讲解Lua GC 的源码剖析 系列 给出作者 ...

  2. 浅谈c#和lua的gc

    前提: 本文参考和借鉴相关博客,相关版权归其所有,我只是做一个归纳整理,所以本文没有任何版权 参考文献和书籍: CLR和.Net对象生存周期:   https://www.cnblogs.com/Wd ...

  3. 【腾讯Bugly干货分享】手游热更新方案xLua开源:Unity3D下Lua编程解决方案

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/2bY7A6ihK9IMcA0bOFyB-Q 导语 xL ...

  4. 手游热更新方案xLua开源:Unity3D下Lua编程解决方案

    C#下Lua编程支持 xLua为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用. xLua的突破 xLua在功能.性能.易用 ...

  5. Cocos2d-x下Lua调用自定义C++类和函数的最佳实践[转]

    Cocos2d-x下Lua调用C++这事之所以看起来这么复杂.网上所有的文档都没讲清楚,是因为存在5个层面的知识点: 1.在纯C环境下,把C函数注册进Lua环境,理解Lua和C之间可以互相调用的本质 ...

  6. 【转】Cocos2d-x下Lua调用自定义C++类和函数的最佳实践

    转自:http://segmentfault.com/blog/hongliang/1190000000631630 关于cocos2d-x下Lua调用C++的文档看了不少,但没有一篇真正把这事给讲明 ...

  7. Win32下 Qt与Lua交互使用(一):配置Qt下Lua运行环境

    偶然间看到Lua这种脚本语言,有点兴趣,简单学习了一下. 发现Lua与C++之间可以实现非常强的交互性.Lua中可以使用C++中的函数,C++中也可以使用Lua中的函数.由此可以引发出很多奇思妙想了. ...

  8. Win32下 Qt与Lua交互使用:配置Qt下Lua运行环境

    Lua与C++之间可以实现非常强的交互性.Lua中可以使用C++中的函数,C++中也可以使用Lua中的函数.由此可以引发出很多奇思妙想了. 简单来说,Lua动态的特性补充了C++的功能.当然,也看你具 ...

  9. Learning Lua Programming (3) iMac下搭建Lua脚本最好的编码环境(代码补全,编译运行)

    这篇文章参考自http://blog.sina.com.cn/s/blog_991afe570101rdgf.html,十分感谢原作者的伟大创造,本人亲测可行. 这篇文章记录一下如何在MAC系统环境下 ...

随机推荐

  1. New FileReader上传图片

    function readURL(input) { if (input.files && input.files[0]) { var reader = new FileReader() ...

  2. tomcat启动时间过长的问题

    阿里云下的服务器安装jdk1.8和tomcat之后出现了一个问题,初次运行tomcat没有问题,可以正常访问tomcat首页,但是关闭之后再重启就发现tomcat首页刷不出来.而且再次关闭之后还报错了 ...

  3. spring boot 2.0.0由于版本不匹配导致的NoSuchMethodError问题解析

    spring boot升级到2.0.0以后,项目突然报出 NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBu ...

  4. Beta第五天

    听说

  5. 项目Alpha冲刺Day7

    一.会议照片 二.项目进展 1.今日安排 今天都是课,主要就是用空闲时间熟悉一下框架使用以及继续进行框架搭建. 2.问题困难 前台界面框架vue和element-ui的写法要适应. 3.心得体会 vu ...

  6. APP案例分析--扇贝单词

    APP案例分析 一.调研 1.第一次上手   第一次使用时,一进APP,有一个每日一句,然后就是登录界面.有点不舒服,我都还不知道你这个APP好不好用,不让我体验一下就要注册.简单的测试了我的英语水平 ...

  7. Alpha冲刺Day2

    Alpha冲刺Day2 一:站立式会议 今日安排: 首先完善前一天的剩余安排工作量,其次我们把项目大体分为四个模块:数据管理员.企业人员.第三方机构.政府人员.数据管理员这一模块,数据管理员又可细分为 ...

  8. 使用Spark MLlib进行情感分析

    使用Spark MLlib进行情感分析             使用Spark MLlib进行情感分析 一.实验说明 在当今这个互联网时代,人们对于各种事情的舆论观点都散布在各种社交网络平台或新闻提要 ...

  9. Struts2之配置

    Struts2的默认配置文件是struts.xml放在/web-inf/classes目录下,struts配置文件的最大作用就是配置Action与请求之间的对应关系,并配置逻辑视图名和物理视图名之间的 ...

  10. 第三篇:Python字符编码

    一 .了解字符编码的知识储备 1计算机基础知识 1.2文本编辑器存取文件的原理(nodepat++,Pycharm,word) #.打开编辑器就打开了启动了一个进程,是在内存中的,所以,用编辑器编写的 ...