http://dlang.org/class.html#destructors处的D文档声明
"垃圾收集器不保证为所有未引用的对象运行析构函数。"
然而,对于这实际意味着什么,我有点cont。。这是说GC实现可以选择在收集它们所属的对象时不调用析构函数吗?如果是这种情况,我几乎看不到destructors中的一个点,因为删除被删除了。
我还可以将其解释为垃圾收集器可能根本不会收集某些对象。虽然更容易理解,但同样令人担忧。这是否意味着收集器可能会导致泄漏?
作为一个后续工作,但我希望仍然在同一问题的范围内,如果其中一个确实如此,是否有任何文档可用于解释如何管理需要析构函数的对象,例如代表资源的对象如果垃圾收集器不能在这些情况下使用,那么除了内存,这似乎暗示在这里?
答案 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。