7

我正在尝试用 Java 编写 DagNode 类,其中两个节点在逻辑上相等,如果它们作为引用相等。

C++(我来自 C++)中的想法是使用智能指针和引用计数:

  • 创建节点后,如果该节点已存在,我将在某个表中查找。如果是这样,我将返回一个指向旧指针的指针。否则,创建一个新节点。

  • 重载的 C++ 方法(如复制构造函数和析构函数)会进行 ref-counting,当节点的 ref-count 降至 0 时,该节点会从上述表中逐出。(C++ 也会释放内存。)

但是,似乎没有办法在 Java 中自动进行引用计数。我需要进行引用计数以知道何时从表中逐出节点(以便对其进行垃圾收集),并且我真的想避免在每个函数的开始和结束时 调用node->incRef()和。node->decRef()

我们如何在 Java 中实现这个 C++ 习语?

4

3 回答 3

6

在 Java 中,参考调查和垃圾是自动的。

但这并不意味着它是完全隐藏的。

如果您想知道何时可以对对象进行垃圾处理,您似乎需要ReferenceQueue ,如果您想保留不会阻止垃圾的指针,则可能需要WeakReference 。

我建议您查看java.lang.ref 包的描述,以找到满足您需求的最佳解决方案。

于 2012-09-14T17:15:52.770 回答
2

创建节点时,如果该节点已经存在,则在某个表中查找,如果存在,则返回指向旧节点的指针,否则创建新节点。

在 Java 中制作这种查找机制并不难。只需使用工厂方法,它会检查“表”并返回相同的实例(如果它已经存在)。

我需要引用计数,所以我知道什么时候从表中驱逐一个节点(所以它可以被垃圾收集)

因为 Java 有这个WeakReference类。它不允许您进行引用计数,但允许在没有人再引用它时对对象进行 GC-ed。

结合这2个,你可以

  • 构造一个填充有WeakReferences的“表”
  • 使用使用 s 的可用 JavaCollection实现之一WeakReference(例如 a WeakHashmap
于 2012-09-14T18:14:51.250 回答
0

用于确定性资源管理的引用计数可以在 Java 中实现。如果您正在使用不由 GC 直接管理的任何类型的系统资源,它会很有用。GC 管理堆内存。但是,如果您使用任何其他类型的资源,例如文件句柄、网络套接字或本机内存,则不能依赖 GC(或其机制,例如 finalization 或 ReferenceQueue),因为您可能会发现您已经分配了所有你的资源,但 GC 仍然没有开始,因为还有大量的 Java 堆内存。(在使用 finalization/ReferenceQueue 时要非常小心——永远不要依赖它们

看看almson-refcount。这是我在找不到任何独立替代方案后为引用计数而创建的库。它非常简单,并受到另一个成熟框架的启发。


关于 OP 的问题,尚不清楚他们真正需要什么。他们绝对没有使用系统资源。听起来他们想要一个与 DAG 平行的 HashMap 以优化get. 显而易见的方法是使 DAG 双向链接,并在节点从 DAG 中删除时从地图中删除节点。他们不需要 WeakReferences 或通用引用计数,尽管两者都可以使用。

于 2018-12-23T12:17:31.087 回答