java - 在这种情况下,什么时候会对我的类实例调用 Finalize() ?

标签 java garbage-collection pass-by-reference finalize

我知道每当垃圾收集器收集类实例时都会调用 Finalize() 。但是,当通过队列将类的实例传递给另一个线程时,我有点困惑。

假设这是 Thread1 的骨架:

for(i=0; i<1000; i++) {
   Packet pkt = new Packet();  // instance of class
   pkt.id = i;
   thread2.queue.put(pkt);
}

然后,线程2将从队列中删除该数据包并执行冗长的操作。第二个线程是否获得数据包的“副本”,或者是否通过某种形式的引用?重要的是,如果是通过复制,则可以在线程 2 处理数据包之前调用线程 1 中创建的实例上的 Finalize()。如果是通过引用,我保证 Finalize() 只会针对数据包中的信息调用一次。

这个基本示例可能没有显示出重要性,但我在数据包中存储了一个 C 指针(来自 JNI),以便在处理完该对象后销毁一些内存。如果通过复制传递,内存可能会在第二个线程完成之前被销毁。如果它是通过引用传递的,那么只有当 GC 发现它不再被两个线程使用时才应该销毁它(我想要的行为)。如果不能保证后一种情况,我将不会使用 Finalize() 并使用其他东西,但它会更复杂。

最佳答案

第二个线程接收相同的实际对象实例。您可以避免过早完成。

它接收对象引用的副本(如果您想这样想的话)。

此外,当垃圾收集器发现对象已成为垃圾时,finalize 不一定会运行 - 虚拟机可以在以后的任何时间自由运行它,并在某个时间实际回收内存在那之后。您确实不能依赖 finalize 何时运行。然而,由于您关心的是知道在第二个线程完成对象之前finalize不会被调用,所以这是无关紧要的。但值得了解!

关于java - 在这种情况下,什么时候会对我的类实例调用 Finalize() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6779019/

相关文章:

javascript - 如何知道使用 document.createElement 创建的元素是否仍然存在

Python - 在不同类的不同实例之间共享变量

java - 获取android中所有已安装应用的名称、图标和包名

java - JUnit4 + Eclipse "An internal error occurred during Launching"

java - 如何在 DialogFragment 中设置一分钟间隔

java - G1GC OutOfMemory 过早

c# - 调用Dispose不会清理对象C#使用的内存?

java - 您能为 Java Web 应用程序推荐一个工作流库或框架吗?

C 通过引用传递变量

c++ - 如何通过参数内部的引用传递对象?