SGen:Mono的生代式垃圾收集器

从API角度来看,Mono正紧紧跟随着.NET的脚步大踏步前进着,但有个关键领域Mono却落后了。Mono中默认的垃圾收集器采用的是可移植、但却不太精确的Boehm-Demers-Weiser保守式垃圾收集器。Boehm垃圾收集器的主要问题在于无法精确读取寄存器与栈帧。因为无法确定给定值到底是指针还是标量,因此它总是假设给定值是指针,并且将相关联的对象标记为存活状态。这么做不仅会错误导致大块内存无法分配,同时还使得压缩可用空间这项工作变得异常艰难。

SGen(Simple Generational)是Mono新一代的垃圾收集器。见名知意,这个持续了两年的项目正尝试替代Mono原来的垃圾收集器,它使用精确的分代式(generational)垃圾收集器,类似于.NET版本的CLR。SGen垃圾收集器使用两生代而非.NET中的三个,但像.NET一样对于大对象使用独立的堆。

在Mono 2.10之前(现在仍处于预览版),SGen仍旧是保守的。新版本增加了对托管栈帧的精确收集的支持,这样基本就不会遇到误报的问题了。来自于p/invoke调用的非托管栈帧仍旧使用保守的方式扫描。

类似于.NET,SGen最大的缺陷在于固定对象。如果将对象固定在SGen中(想想.NET中的0生代),那么它就无法彻底清除,这会导致内存碎片。由于几个原因,SGen的这个问题甚至更糟。你不仅需要处理碎片,而且SGen需要从这些碎片中分配内存。理想情况下,所有的活动对象都应从SGen中复制出来,并且得到重用。

为了解决这些问题,SGen并不仅仅像.NET那样检测显示的固定对象。如前所述,对非托管栈帧的保守式扫描会导致对象的固定,这是因为栈中的数字值可能碰巧与内存地址一样。据推测,随着与p/invoke调用相关的逻辑变得更加可靠,这将在未来的版本中得到修复。

查看英文原文:SGen: Mono’s Generational Garbage Collector

你可能感兴趣的:(SGen:Mono的生代式垃圾收集器)