分析完前端的mpl2mpl,我已经大致了解了方舟编译器把源码转换成中端IR可识别形式的过程中做的事情。方舟编译器能够把各种语言都转换成自己想要的格式,本地库的映射数量要有多少我无法想象,亦不清楚这是一个“降维打击”的过程还是”量变引起质变“的堆砌。但是这一部分我无从得知,只能继续下一部分的研究了。
这一周我主要学习了方舟中的垃圾回收机制。
首先,什么是垃圾回收?
大一上学期的JAVA课里,我学习了JVM的垃圾回收机制:垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制,垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身。
在JVM中GC要做的事情,第一是找出所有未被回收的对象,第二要判断哪些是无用的对象,第三是回收被这些无用对象占用的内存空间。用到的算法包含引用计数算法(RC)和根搜索(TC)算法。由于引用计数法难以检测出对象之间的循环引用所以java选择了根搜索算法。根搜索是指以“GC Roots”为起点,寻找对应的引用节点,一直向下寻找直到形成一棵节点树,没有包含在内的对象就是不可用的,这样一种算法。
回收垃圾对象内存时使用的算法四种。
(1) Tracing算法:按照前面根搜索到过程,遍历节点树之后标记不可用对象,然后分别进行内存释放。缺点是需要另外建一个空闲列表记录所有空闲区域及其大小,清理后产生的不连续空内存也不方便使用。
(2) Compacting算法:标记好不可用对象后让它们集中起来,然后一次性清理掉这部分内存。缺点是GC耗费时间长,毕竟需要把所有对象拷贝到新的地方,然后更新它们的引用地址。
(3) Copying算法:将一块内存分为大小相等的两块,每次只使用其中一块,用完之后把仍然可用的对象复制到另一块上,再把已使用的那一块一次清理掉。缺点是,可一次性分配的最大内存缩小了一半。
(4) Adaptive算法:其实这并不是一种具体的算法,而是一种优化算法的算法,根据当前堆的使用情况,选择适当的垃圾收集器。
那么说了这么多,方舟编译器的GC机制是什么样的呢?
方舟编译器采用的是RC技术优化算法+消除环算法,也就是前文中我们说到被JVM抛弃的引用计数算法,但是缺陷依然存在:计数本身占用大量资源,循环计数不能解决。为此方舟编译器改进了RC算法。方舟给环结构引入了标记处理,并采用了消除环算法,同时在运行状态下也加入了环回收机制。
这一部分内容在me_rc_lowing.cpp文件里,文件包括了RC准备,RC预降级,RC降级以及RC方法执行几部分。计数降级步骤是基于预先分析结果生成一个计数参数赋值的本地RC函数。该本地函数在目标代码生成过程中会被降级以满足方舟编译器的IR层使用。
垃圾回收机制的分析就先到这里,下周再继续分析。