Pup*_*ppy 24 c++ garbage-collection c++11
我正在C++ 0x中实现一个压缩垃圾收集器供我个人使用,我有一个问题.显然,收集器的机制取决于移动对象,我一直想知道如何根据指向它的智能指针类型来实现它.我一直在考虑指针类型本身的指针指针,或者,收集器维护一个指向每个对象的指针列表,以便可以修改它们,从而在访问时无需双重de-ref指针但在收集期间添加一些额外的开销和额外的内存开销.什么是最好的方式去这里?
编辑:我主要关心的是快速分配和访问.我并不关心特别有效的收藏或其他维护,因为这不是GC的目的.
Ytt*_*ill 11
关于将额外的GC移植到C++,没有什么是直接的,更不用说压缩算法了.目前尚不清楚你正在尝试做什么以及它将如何与其余的C++代码进行交互.
我实际上用C++编写了一个gc,它可以使用现有的C++代码,并且在一个阶段就有一个压缩器(虽然我放弃它因为它太慢了).但是有许多令人讨厌的语义问题.几周前我才向Bjarne提到C++缺乏正确执行操作所需的操作符,而且情况是它不太可能存在,因为它的实用性有限.
你真正需要的是一个"re-addres-me"运算符.发生的事情是你实际上没有移动物体.您只需使用mmap更改对象地址.这要快得多,实际上,它使用VM功能来提供句柄.
如果没有这个功能,你必须有一种方法来执行一个对象的重叠移动,这是你无法有效地在C++中完成的:你必须首先移动到临时.在C中,它可以更容易使用memmove.在某个阶段,必须调整所有指向或移动对象的指针.
使用手柄并没有解决这个问题,它只是减少了从任意大小的天体恒定尺寸的,这个问题:这些都是比较容易在一个阵列来管理,但存在同样的问题:你要管理存储.如果从数组中随机删除大量句柄,则仍然存在碎片问题.
所以不要打扰句柄,它们不起作用.
这就是我在菲利克斯所做的:你打电话new(shape, collector) T(args).这里shape是类型的描述符,包括包含(GC)指针的偏移列表,以及完成对象的例程的地址(默认情况下,它调用析构函数).
它还包含一个标志,说明是否可以移动对象memmove.如果对象很大或不可移动,则由它分配malloc.如果对象很小且移动,则在竞技场中分配,如果竞技场中有空间.
通过移动其中的所有对象来压缩竞技场,并使用形状信息全局调整指向这些对象的所有指针.压缩可以逐步完成.
C++程序员的缺点是需要构造一个正确的shape对象来传递.这并没有打扰我,因为我正在实现一种可以自动生成形状信息的语言.
现在:关键点是:要进行压缩,必须使用精确的收集器.压缩无法与保守的收集器一起使用.这是非常重要的.如果你看到一个看起来像指针但恰好是整数的值,允许一些泄漏是很好的:一些对象不会被收集,但这通常没什么大不了的.但是对于压缩,你必须调整指针,但你最好不要改变那个整数:所以你必须确定什么东西是指针,所以你的收集器必须精确:形状必须是已知的.
在Ocaml中,这是相对简单的:一切都是指针或整数,并且在运行时使用低位来表示.指向的对象有一个告诉类型的代码,并且只有几种类型:标量(不扫描它)或聚合(扫描它,它只包含整数或指针).
这是一个非常简单的问题,所以这里有一个简单的答案:
Mark-and-sweep(有时mark-and-compact是为了避免堆碎片)在分配和访问方面是最快的(避免双重取消引用)。它也很容易实现。由于您不担心收集性能影响(标记和清除往往会不确定地冻结进程),因此这应该是正确的选择。
实施细节见: