D垃圾收集器是什么意思并不能保证为所有未引用的对象运行析构函数"?

时间:2015-06-16 16:52:14

标签: garbage-collection d destructor finalizer

http://dlang.org/class.html#destructors处的D文档声明

  

"垃圾收集器不保证为所有未引用的对象运行析构函数。"

然而,对于这实际意味着什么,我有点cont。。这是说GC实现可以选择在收集它们所属的对象时不调用析构函数吗?如果是这种情况,我几乎看不到destructors中的一个点,因为删除被删除了。

我还可以将其解释为垃圾收集器可能根本不会收集某些对象。虽然更容易理解,但同样令人担忧。这是否意味着收集器可能会导致泄漏?

作为一个后续工作,但我希望仍然在同一问题的范围内,如果其中一个确实如此,是否有任何文档可用于解释如何管理需要析构函数的对象,例如代表资源的对象如果垃圾收集器不能在这些情况下使用,那么除了内存,这似乎暗示在这里?

1 个答案:

答案 0 :(得分:6)

这意味着:垃圾收集器可能永远不会运行(今天D中的GC仅在您要求内存并且已经处于其阈值或程序终止时运行)并且当它运行时,它可能无法收集某些内容,主要是由于32位的错误指针。 (随机值看起来像是指向数据的指针,因此GC认为它可能是,因此不会收集对象。)

错误的指针在64位上非常罕见,但在32位代码中有点容易触发,而且不运行GC实际上是你追求性能的常见事情:你希望它能够在你负担得起的时候运行收集垃圾时暂停。

如果某个对象代表某个其他资源,您可能希望完全避免在垃圾收集环境中使用它。相反,将它包装在结构而不是类中,并在某个顶级范围内保持它的所有权,将其作为指向结构的指针传递,或者将其放在类似RefCounted(参见std.typecons)的内容中,以便以这种方式进行管理。

或者,在您的课程上编写dispose方法,并在完成后手动调用:

class YourDisposable {
    HANDLE managed_object;
    this() { managed_object = acquire_resource(); }
    void dispose() {
       if(managed_object !is null) {
             release_resource(managed_object);
             managed_object = null;
       }
    }

    ~this() {
         dispose();
    }
}

 auto obj = new YourDisposable();
 scope(exit) obj.dispose();

通过这种方式,您通常会自行销毁它,以便可以预测地发布它,但是如果您错过了某个地点或者所有权太难以手动管理,也可以使用GC。