在Clojure中模拟析构函数

时间:2012-10-10 03:55:55

标签: java clojure

问题陈述

我有两台机器,A和B,都运行Clojure。

B有一些内存数据结构。

A保存一个对象A_P,它是B内存中某个对象B_O的引用/指针。

现在,只要A_P不是由A进行GC编辑,我就不希望B由B-GC编辑。

然而,一旦A_P由A进行GC编辑(A中没有任何其他内容参考B_O,B中没有其他内容指B_O),那么我希望B_O能够被选中进行GC编辑。

使用析构函数的语言解决方案

在C ++中,这很简单 - 我使用析构函数。当A_P得到GC-ed时,A发送B一个msg来减少对B_O的外部引用数,当它为0时,内部引用到B_0也为0,则B_O得到GC-ed。

Java / Clojure中的解决方案?

现在,我知道Java没有析构函数。但是,我想知道Clojure是否能解决这个问题。

谢谢!

4 个答案:

答案 0 :(得分:3)

没有真正的分布式垃圾收集器,没有好的解决方案。即使在C ++中,也无法安全地执行此操作,因为您实现了引用计数并假装它是一个真正的垃圾收集器;但是如果两个对象在整个机器之间相互指向,并且都是在本地未引用的,那么它们仍然具有非零引用计数而无法收集。

答案 1 :(得分:1)

不,由于JVM的自动内存管理模型,Clojure(基于JVM,CLR)没有“C ++类型析构函数”。有终结器之类的东西,但建议不要使用它们。相反,您应该根据消息传递机制建模您的解决方案,而不是在B中持有“指针/引用”的机器。我知道这个答案非常高,因为您没有在您的问题中提供任何特定的问题详细信息。如果您需要有关如何解决特定问题的更多详细信息,请提供完整的上下文,我相信有人可以帮助您。

答案 2 :(得分:1)

这是一个固有的难题:分布式垃圾问题非常困难,如果不是不可能的话。

但是,您可能只能使用Java终结器并覆盖finalize()方法。然后,您可以实现类似于您为C ++描述的消息传递技术。

这将在更一般的情况下出现问题(它不会帮助你在机器上进行循环引用,因为合金指出)并且还有一些其他的怪癖需要注意(主要是因为你无法完全控制何时终结者被召唤)但你可能能够让它在你的特定情况下工作。

答案 3 :(得分:0)

假设您正在使用像ref或atom这样的数据结构来保存其中的某个地方的数据结构,您可以使用侦听器来监视该结构的状态以删除A,并且这些侦听器可以向B发送适当的消息。clojure.data/diff对于找到被移除的结构非常有用。

另一种选择是,在取消引用A结构之后,负责这样做的功能发送消息。但是,作为其中的一部分,请确保该代码实际上负责删除A,而不是其他更新。