我为Postscript虚拟机编写了一个简单的垃圾收集器,我很难设计一套适当的规则来何时进行收集(当空闲列表太短时?)以及何时分配新的空间(当有很多空间可供使用时?)。
到目前为止,我自下而上写过,但这个问题涉及顶级设计。所以我觉得自己处于摇摇欲坠的状态。 所有对象都是通过操作员函数进行管理和访问的,因此这是 C中的收集器,而不是中的。
主分配器功能称为gballoc
:
unsigned gballoc(mfile *mem, unsigned sz) {
unsigned z = adrent(mem, FREE);
unsigned e;
memcpy(&e, mem->base+z, sizeof(e));
while (e) {
if (szent(mem,e) >= sz) {
memcpy(mem->base+z, mem->base+adrent(mem,e), sizeof(unsigned));
return e;
}
z = adrent(mem,e);
memcpy(&e, mem->base+z, sizeof(e));
}
return mtalloc(mem, 0, sz);
}
我确定在不知道所有类型和功能意味着什么的情况下是乱码,所以这里是同一功能的伪代码:
gballoc
load free list head into ptr
while ptr is not NULL
if free element size is large enough
return element, removed from list
next ptr
fallback to allocating new space
所以它是一个简单的“先适合”算法,没有雕刻(但是分配保留了它们的大小;因此,对于小对象重用的大空间可以在以后再次用于大对象。)
但什么时候应该拨打collect()
?
编辑: 其余代码和相关模块已发布在线程中的comp.lang.postscript中: http://groups.google.com/group/comp.lang.postscript/browse_thread/thread/56c1734709ee33f1#
答案 0 :(得分:1)
有几种适用的理念:
作为垃圾收集的开发者,可能需要为应用程序选择策略,因为它可能知道哪个是最有效的。当然,如果它没有首选项,您应该选择默认值。
答案 1 :(得分:1)
这是包含在原始代码中的定期收集策略:
enum { PERIOD = 10 };
unsigned gballoc(mfile *mem, unsigned sz) {
unsigned z = adrent(mem, FREE);
unsigned e;
static period = PERIOD;
memcpy(&e, mem->base+z, sizeof(e));
try_again:
while (e) {
if (szent(mem,e) >= sz) {
memcpy(mem->base+z, mem->base+adrent(mem,e), sizeof(unsigned));
return e;
}
z = adrent(mem,e);
memcpy(&e, mem->base+z, sizeof(e));
}
if (--period == 0) {
period = PERIOD;
collect(mem, 0);
goto try_again;
}
return mtalloc(mem, 0, sz);
}