6

虽然我认为我理解问题的要点(即一个好的 GC 跟踪对象,而不是范围),但我对主题的了解不足以说服其他人。

你能解释一下为什么没有带有确定性析构函数的垃圾收集语言吗?

4

3 回答 3

3

它们不是相互排斥的。随意将 C++ 与 libgc(Boehm-Reiser-Detlefs 收集器)一起使用。您仍然可以使用 RAII、智能指针和手动删除,但是在运行 GC 的情况下,您也可以“忘记”删除一些对象。

@Andy 关于资源被处理得太晚的回答忽略了重要的一点:不是延迟释放资源在语义上至关重要,而是释放的顺序。

GC 不能很好地排序发布的原因是它需要对排序要求(依赖项)进行拓扑排序,这是一种昂贵的算法。

尽管如此,Ocaml GC 有一个有趣的工具,您可以在其中将终结器附加到对象。如果对象变得无法访问,则运行终结器,但不会删除对象(因为终结器可以使其再次可达:在这种情况下,您甚至可以附加另一个终结器)。这些终结器可以提供对排序的一些控制。

于 2011-01-17T13:22:33.057 回答
0

来自Wikipedia,在注意到跟踪垃圾收集器是最常见的类型之后:

跟踪垃圾收集不是确定性的。符合垃圾回收条件的对象通常最终会被清理,但无法保证何时(或什至)会发生。

因此,依赖 RAII 可能会导致资源被处理得太晚。

因此,例如,Java 有一个“避免终结器”的指南(Josua Bloch 的“Effective Java”中的第 6 条)。“在终结器中不应该做任何时间紧迫的事情。”

于 2011-01-12T18:15:03.667 回答
0

垃圾收集器不能一直运行(引用计数越来越近,但通常不算作垃圾收集),所以它甚至不尝试。这很不切实际。因此,在对象变得不可访问(例如,因为唯一的引用超出范围)和 GC 收集它之间存在不可避免的延迟,可能会触发终结器。这种延迟不是确定性的......除非(然后,在最严格的意义上,确定性破坏是可能的,尽管仍然不切实际)迫使 GC 进入确定性计划 - 但这非常接近“GC 一直在运行” ,这仍然是非常不切实际的。

所以 GC 和确定性清理是相互排斥的,因为 GC 会完成所有清理工作,它不能承担确定性,但必须依靠最大化其效率。

于 2011-01-12T18:17:31.963 回答