我正在尝试用Java编写DagNode类,其中两个节点在逻辑上相等,如果它们作为引用相等。
C++中的理念—(我来自C++)—将使用智能指针和引用计数:
-
当创建一个节点时,如果该节点已经存在,我会在某个表中查找。如果是,我将返回一个指向旧指针的指针。否则,创建新节点。
-
重载的C++方法(如复制构造函数和析构函数)将进行引用计数,当节点的引用计数降至0时,该节点将从上述表中逐出。(C++也将释放内存。)
然而,在Java中似乎没有办法自动进行引用计数。我需要进行ref计数,以知道何时从表中逐出节点(这样就可以对其进行垃圾收集),并且我确实希望避免在每个函数的开始和结束时调用node->incRef()
和node->decRef()
。
我们如何在Java中实现这个C++习惯用法?
在Java中,引用调查和垃圾是自动的。
但这并不意味着它是完全隐藏的。
如果您想知道对象何时可以被乱码,您似乎需要ReferenceQueue,如果您想保留不能防止垃圾的指针,则可能需要WeakReference。
我建议您查看java.lang.ref包的描述,以找到适合您需要的最佳解决方案。
创建节点时,如果该节点已经存在,则在某个表中查找,如果已经存在,只返回一个指向旧节点的指针,否则创建新节点。
在Java中创建这种查找机制并没有那么困难。只需使用一个工厂方法,它会检查一个"表",并在该表已经存在的情况下返回相同的实例。
我需要引用计数,这样我就知道什么时候从表中逐出节点(这样它就可以被垃圾收集)
因为Java有WeakReference
类。它不允许您进行引用计数,但允许在没有人再引用对象时对其进行GC ed。
把这2个组合起来,你就可以
- 构造一个用
WeakReference
填充的"表"> - 使用使用
WeakReference
的可用JavaCollection
实现之一(例如WeakHashmap
)
用于确定性资源管理的引用计数可以在Java中实现。如果您使用的是不由GC直接管理的任何类型的系统资源,那么它可能会很有用。GC管理堆内存。但是,如果您使用任何其他类型的资源,如文件句柄、网络套接字或本机内存,您就不能依赖GC(或其机制,如终结或ReferenceQueue),因为您可能会发现您已经分配了所有资源,但GC仍然没有启动,因为还有大量的Java堆内存。(在使用finalization/ReferenceQueue时要非常小心——永远不要依赖它们)
看一看济贫院院长。这是我在找不到任何独立的替代品后创建的一个库,用于参考计数。它非常简单,灵感来自另一个成熟的框架。
关于OP的问题,尚不清楚他们实际需要什么。他们肯定没有使用系统资源。听起来他们想要一个与DAG并行的HashMap来优化get
。显而易见的方法是使DAG双重链接,并在从DAG中删除节点时从映射中删除节点。它们不需要WeakReferences或通用引用计数,尽管两者都可以使用。