什么时候会在这种情况下对我的类实例调用finalize()? [英] when will finalize() be called on my class instance in this scenario?

查看:144
本文介绍了什么时候会在这种情况下对我的类实例调用finalize()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



假设这是Thread1的骨架:

(i = 0; i <1000; i ++){
Packet pkt = new Packet();

  //类的实例
pkt.id = i;
thread2.queue.put(pkt);





$ b然后,线程2将从队列中移除数据包并执行冗长的操作。这第二个线程是否获得了数据包的副本,还是通过某种形式的参考?重要的是,如果是通过复制,线程1中创建的实例的finalize()可以在线程2完成数据包之前调用。如果是通过引用,我保证finalize()只会被调用一次包中的信息。



这个基本的例子可能不显示重要性,但我我在数据包中存储了一个C指针(来自JNI),以便在完成对象时摧毁一些内存。如果它通过复制传递,内存可能会在第二个线程完成之前被销毁。如果它通过引用传递,那么只有在GC看到它不再被两个线程使用时(我期望的行为),它才应该被销毁。如果后面的情况不能保证,我不会使用finalize()并使用其他的东西,但它会更复杂。 第二个线程接收相同的实际对象实例。第二个线程接收相同的实际对象实例。如果你想这样想的话,它会收到一份对象引用的副本。



另外,当垃圾收集器发现该对象已变为垃圾时, c> finalize 不一定会运行 - 虚拟机随后可以自由运行时间,并在此之后实际回收内存。当 finalize 将会运行时,你真的不能依赖它。然而,因为你关心的是在第二个线程完成对象之前知道> 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.

解决方案

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!

这篇关于什么时候会在这种情况下对我的类实例调用finalize()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆