1.7 写屏障和垃圾收集器
Next: Serialization Formats,Previous: Autoprinting,Up: R Internal Structures
1.7 写屏障和垃圾收集器
从 1.2.0 版本开始 R 有一个改进的垃圾收集器(garbage collector)。sxpinfo头文件的二进制位gcgen用于实现这个。它和mark二进制位联合使用以确定之前的两代(two previous generations)。
有三个层次的收集器。0层次仅仅收集最年轻的一代,1层次收集两个年轻的代,而2层次手机所有代的。在20个层次为0的收集器之后,下一个收集器是在1层次,并且在5个层次为1的收集器后是2层次的收集器。此外,如果一个层次-n的收集器不能提高20%的自由空间(为每个节点和向量内存堆),下一个收集器将会在n+1层次。(R层次的函数gc()执行2层次的收集器。)
改进的垃圾收集器需要有效地判断一个对象的`年龄',特别是和列表类似的对象(包括STRSXP)。这通过确定一个列表的元素至少像这个列表被赋值时一样老来判断对象年龄。函数SET_VECTOR_ELT 和 SET_STRING_ELT用于处理这个过程,这是这两个函数不是宏的原因。保证这种操作完整性有一个专门的术语,就是写屏障(write barrier)。这一过程通过让SEXP不透明以及利用函数来提供访问(不能在C里面赋值是用于左值(lvalues))来实现。
R扩展的所有代码默认都是放置在写屏障后面的。直接访问SEXPREC内部的唯一方法是在导入头文件Rinternals.h前定义通常在头文件Defn.h 里面定义的USE_RINTERNALS。为允许检验使用的存取方式, R 在编译的时候可以加上标签--enable-strict-barrier以保证 Defn.h 不会定义 USE_RINTERNALS,从而使得在大部分 R 里面SEXP 不是透明的。 (有一些必要的例外: 最初的 memory.c 定义存取函数和 size.c需要访问内部结构的大小。)
原始文献可以参考http://www.stat.uiowa.edu/~luke/R/barrier.html 和http://www.stat.uiowa.edu/~luke/R/gengcnotes.html。
Hits:Loading...
