如何为自定义标记扫描收集器安排收集周期?

Posted

技术标签:

【中文标题】如何为自定义标记扫描收集器安排收集周期?【英文标题】:How to schedule collection cycles for custom mark-sweep collector? 【发布时间】:2011-09-16 01:10:35 【问题描述】:

我已经为 Postscript 虚拟机编写了一个简单的垃圾收集器,但我很难为何时进行收集(空闲列表太短时?)以及何时分配新的空间(当有很多空间可以使用时?)。

到目前为止,我都是自底向上写的,但是这个问题涉及到顶层设计。所以我觉得我在摇摇欲坠的基础上。 所有对象都被管理并且只能通过操作符函数访问,所以这是一个收集器in C,而不是for 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#

【问题讨论】:

【参考方案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);

【讨论】:

不要告诉任何人,但这实际上不起作用。 collect 的第二个参数应该是包含根集的堆栈结构的地址。但我将不得不制作一系列指向多个堆栈的特殊实体。并且针对不同的内存文件进行不同的设置。但至少电话已经到位。【参考方案2】:

有几种适用的哲学:

将垃圾收集作为最后一招,避免在分配期间扩展堆。这可能是最常见的策略。 定期进行垃圾收集,例如每百分之一的分配或释放。在某些情况下,这可能不会让碎片失控,从而减少垃圾收集的整体工作量。 不要进行任何垃圾收集。始终是一种可行的策略,尤其是对于短期或简单的程序。

作为垃圾收集的开发人员,最好将策略选择权交给应用程序,因为它可能知道哪种策略最有效。当然,如果它没有偏好,你应该选择一个默认的。

【讨论】:

是的,有一个用户级操作员vmreclaim 可以(启用/禁用)自动收集,或请求立即收集。因此,规范中已经涵盖了您的第三个选项。期刊目前似乎是一个合理的选择。除非有足够的初始资金池,否则我担心初创公司会因最后一搏策略而陷入困境。 我希望能找到更多答案可供选择;但这给了我现在需要的东西,并为未来的思考提供了素材。所以我接受。谢谢。

以上是关于如何为自定义标记扫描收集器安排收集周期?的主要内容,如果未能解决你的问题,请参考以下文章

如何为自定义相机添加 取景框|扫描框 |预览框|矩形框

如何为 sklearn 的 CountVectorizer 编写自定义标记器以将所有 XML 标记以及打开和关闭标记之间的所有文本视为标记

如何为uitableview自定义多选编辑模式

Android - 如何为整个应用程序设置自定义字体[重复]

springboot自定义注解收集操作日志

springboot自定义注解收集操作日志