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

发布于 2024-11-25 05:56:00 字数 593 浏览 2 评论 0原文

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

假设这是线程 1 的骨架:

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() 并使用其他东西,但它会更复杂。

I know that finalize() is called whenever a class instance is collected by the garbage collector. However, I am a little bit confused when passing an instance of a class to another thread via a queue.

Let's say this is a skeleton of Thread1:

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

Then, thread 2 will remove the packet from the queue and perform lengthy operations. Does this second thread get a "copy" of the packet, or is it by some form of reference? The importance is that, if it is by copy, the finalize() on the instance created in thread 1 can be called before thread 2 is done with the packet. If it is by reference, I am guaranteed that finalize() is only called once for the information in the packet.

This basic example may not show the importance, but I am storing a C-pointer (from JNI) in the packet to destroy some memory when I am done with the object. If it is passed by copy, the memory may get destroyed before the second thread is done with it. If it is passed by reference, then it should only be destroyed once the GC sees it is no longer in use by BOTH threads (my desired behavior). If this latter scenario is not guaranteed, I will not use finalize() and use something else but it will be more complex.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

屌丝范 2024-12-02 05:56:00

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

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

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

The second thread receives the same actual object instance. You're safe from premature finalization.

It receives a copy of the object reference, if you want to think of it that way.

In addition, finalize is not necessarily run when the garbage collector finds that the object has become garbage - the VM is free to run it at any later time, and to actually reclaim the memory some time after that. You really can't rely on when finalize will be run. However, since what you care about is knowing that finalize won't be called before the second thread finishes with the object, that's immaterial. But worth knowing!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文