代码之家  ›  专栏  ›  技术社区  ›  VoidPointer

如何检测对象何时不再被引用

  •  9
  • VoidPointer  · 技术社区  · 16 年前

    是否有一种方法来创建一个注册处理程序,该处理程序将在释放对某个对象的最后一个引用时被调用?

    例如,一个由物理数据文件支持的对象,一旦该对象变为未引用对象,该文件应关闭,而不是重命名。如果可以这样做而不必显式调用该对象上的“close”方法,那就太好了。

    我从弱/幻影参考区域了解到的所有通知机制都只说明通知将在某个时间点发生,但不确定何时发生…

    7 回复  |  直到 11 年前
        1
  •  13
  •   Jason Cohen    16 年前

    简而言之, 不。

    Java规范明确地拒绝了您知道最后一个引用何时被释放的能力。JVM实现(和优化)依赖于此。没有钩子。

        2
  •  4
  •   dl__    16 年前

    根据我的理解,我找了一些时间来查找Java对象的“析构函数”,没有办法知道什么时候丢失最后一个引用。Java跟踪对象的引用,但出于性能原因,仅在垃圾收集期间更新此信息。

    最接近的是finalize方法,它应该在垃圾收集期间调用,但不能保证即使在那时也会调用它。

        3
  •  4
  •   James Schek    16 年前

    我想Weakreference会做你想做的。weakreference在弱可到达时(即所有强引用都消失了),它就会被放入referencequeue中。

    本文作者: Ethan Nicholas .

    如果您担心某些引用在关闭时无法到达引用队列,那么请保留所有创建的对象的列表(使用weakreferences或phantomreferences)。添加一个关闭挂钩,检查列表中是否有任何未完成的引用,并执行您需要的任何操作。

        4
  •  2
  •   James Curran    16 年前

    问题是,“在没有对象引用的情况下,如何实现这个?”

    即使您可以通过这个问题,比如说通过一个服务,我们将调用handlemanager,handlemanager也必须创建一个新的对象引用,才能传递给您的处理程序。然后,您的处理程序可以(a)存储对它的引用,这会混淆期望销毁未引用对象的handlemanager;或者(b)释放引用,这意味着最终引用再次被释放,这意味着必须再次调用处理程序….

        5
  •  2
  •   Community noseratio    7 年前

    如果需要像文件一样管理外部资源,在Java中最好的是一个关闭()函数(无论您选择什么名称)。您可以使用finalize()作为“腰带和吊带”保险单,但这有不可预知的时间。所以您的主要防御线需要是close()函数。

    看我的答案 Why would you ever implement finalize()?

        6
  •  0
  •   Steven Huwig    16 年前

    这不能用Java来完成——就我所知,它需要一个引用计数垃圾收集器。您是否考虑过根据需要打开和关闭对象的物理数据文件,而不是在对象的生命周期内保持它的打开状态?

        7
  •  -1
  •   matt b    16 年前

    能够 重写 finalize() 但由于其他人提到的原因,这是有问题的。

    对于您的特定示例,您可以查看使用 File.deleteOnExit() ,这将在VM退出后删除该文件。