为什么RAII和垃圾收集是互斥的?

时间:2011-01-12 18:04:59

标签: language-agnostic garbage-collection raii

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

您能否解释为什么没有垃圾收集语言和确定性析构函数?

3 个答案:

答案 0 :(得分:3)

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

@ Andy关于资源处置太晚的答案错过了重要的一点:释放资源的延迟不是语义上的关键,而是释放的顺序。

GC倾向于不顺序发布的原因是它需要对排序要求(依赖性)进行拓扑排序,这是一种昂贵的算法。

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

答案 1 :(得分:0)

Wikipedia开始,注意到跟踪垃圾收集器是最常见的类型:

  

跟踪垃圾收集不是   确定性。成为的对象   有资格进行垃圾收集   通常最终会被清理干净但是   无法保证何时(甚至是   如果)那将会发生。

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

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

答案 2 :(得分:0)

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

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