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

Val*_*ity 2 garbage-collection destructor d finalizer

http://dlang.org/class.html#destructors上的D文档说明了这一点

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

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

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

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

Ada*_*ppe 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();
Run Code Online (Sandbox Code Playgroud)

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