D垃圾收集器是"not guaranteed to run the destructor for all unreferenced objects"是什么意思?
What does it mean that the D garbage collector is "not guaranteed to run the destructor for all unreferenced objects"?
http://dlang.org/class.html#destructors 的 D 文档指出
"The garbage collector is not guaranteed to run the destructor for all unreferenced objects."
但是我有点困惑这到底是什么意思。这是不是说一个GC实现在收集它们所属的对象时可以选择不调用析构函数?如果是这种情况,我几乎看不到析构函数中的一点,因为 delete 已被弃用。
我也可以将其解释为垃圾收集器可能永远不会收集某些对象。这虽然更容易理解,但似乎同样令人担忧。这是否意味着收集器可能会导致泄漏?
作为后续跟进,但我希望仍在同一个问题的范围内,如果确实存在其中一个问题,是否有可用的文档解释如何管理需要析构函数的对象,例如那些如果在这些情况下不能使用垃圾收集器,那么代表内存以外的资源,就像这里暗示的那样?
这意味着两者:垃圾收集器可能永远不会 运行(今天 D 中的 GC 只有 运行s 当你向它请求内存并且它已经达到阈值或程序终止时)当它 运行 时,它可能不会收集任何东西,主要是由于 32 位上的错误指针。 (一个随机值看起来像一个指向数据的指针,所以 GC 认为它可能是,因此不收集对象。)
错误指针的事情在 64 位上极为罕见,但在 32 位代码中有点容易触发,而不是 运行宁 GC 实际上是您追求性能的常见事情:您想要它到 运行 当您可以在它收集垃圾时暂停一下。
如果一个对象代表一些其他资源,您可能希望完全避免在垃圾收集环境中使用它。相反,将它包装在一个结构中而不是 class 并在某个顶级范围内维护它的所有权,将它作为指向结构的指针向下传递,或者将它放在类似 RefCounted 的东西中(参见 std.typecons)所以它是这样管理的。
或者,在您的 class 上编写一个 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,以防您错过一个地点或所有权太难手动管理。
http://dlang.org/class.html#destructors 的 D 文档指出
"The garbage collector is not guaranteed to run the destructor for all unreferenced objects."
但是我有点困惑这到底是什么意思。这是不是说一个GC实现在收集它们所属的对象时可以选择不调用析构函数?如果是这种情况,我几乎看不到析构函数中的一点,因为 delete 已被弃用。
我也可以将其解释为垃圾收集器可能永远不会收集某些对象。这虽然更容易理解,但似乎同样令人担忧。这是否意味着收集器可能会导致泄漏?
作为后续跟进,但我希望仍在同一个问题的范围内,如果确实存在其中一个问题,是否有可用的文档解释如何管理需要析构函数的对象,例如那些如果在这些情况下不能使用垃圾收集器,那么代表内存以外的资源,就像这里暗示的那样?
这意味着两者:垃圾收集器可能永远不会 运行(今天 D 中的 GC 只有 运行s 当你向它请求内存并且它已经达到阈值或程序终止时)当它 运行 时,它可能不会收集任何东西,主要是由于 32 位上的错误指针。 (一个随机值看起来像一个指向数据的指针,所以 GC 认为它可能是,因此不收集对象。)
错误指针的事情在 64 位上极为罕见,但在 32 位代码中有点容易触发,而不是 运行宁 GC 实际上是您追求性能的常见事情:您想要它到 运行 当您可以在它收集垃圾时暂停一下。
如果一个对象代表一些其他资源,您可能希望完全避免在垃圾收集环境中使用它。相反,将它包装在一个结构中而不是 class 并在某个顶级范围内维护它的所有权,将它作为指向结构的指针向下传递,或者将它放在类似 RefCounted 的东西中(参见 std.typecons)所以它是这样管理的。
或者,在您的 class 上编写一个 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,以防您错过一个地点或所有权太难手动管理。