Tag: finalize

什么时候执行finalize()?

在一次采访中我被问到,假设JVM在没有使用A类的对象时运行gc。 class A{ //some code here protected void finalize(){ //code here } } 它确保执行finalize()。 我说是 接下来的问题是如果正在使用类A的obj,如果现在JVM运行GC它会执行finalize()。 我说不,它不会执行此finalize(),因为JVM不会收集A的对象。 然而,她没有发表评论,但看起来很失望。 我解释错了吗? 提前致谢

在这种情况下何时会在我的类实例上调用finalize()?

我知道每当垃圾收集器收集一个类实例时都会调用finalize()。 但是,当通过队列将类的实例传递给另一个线程时,我有点困惑。 假设这是Thread1的骨架: for(i=0; i<1000; i++) { Packet pkt = new Packet(); // instance of class pkt.id = i; thread2.queue.put(pkt); } 然后,线程2将从队列中删除数据包并执行冗长的操作。 这第二个线程是否获得了数据包的“副本”,还是通过某种forms的引用? 重要的是,如果它是通过复制,则可以在线程2完成数据包之前调用在线程1中创建的实例上的finalize()。 如果它是通过引用,我保证只对包中的信息调用finalize()一次。 这个基本示例可能没有显示重要性,但我在数据包中存储了一个C指针(来自JNI),以便在完成对象时销毁一些内存。 如果它是通过副本传递的,则内存可能会在第二个线程完成之前被销毁。 如果它是通过引用传递的,那么它应该只在GC看到BOTH线程不再使用它时才被销毁(我想要的行为)。 如果后一种情况得不到保证,我不会使用finalize()并使用其他东西,但会更复杂。

对象未完成,Finalizer线程没有做任何事情

在我们的服务器上,我们开始遇到OutOfMemoryError问题。 我们使用Eclipse Memory Analysis分析了堆转储,并发现许多对象被认为是最终确定的(大约是堆的2/3): 我们发现,它可能是一些finalize()方法阻塞。 我发现了这个问题的几个错误报告( 这里或这里 ),它总是在Finalizer线程堆栈中表现出来,它在某个地方被阻止了。 但在我们的例子中,这个post是等待的: “Finalizer” daemon prio=10 tid=0x43e1e000 nid=0x3ff in Object.wait() [0x43dfe000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) – waiting on (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133) – locked (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189) 编辑: 然后我们尝试添加-XX:+UseConcMarkSweepGC ,但没有成功,只有OutOfMemoryError的频率减少了,所以我们首先想到它有所帮助。 最后,我们怀疑JVM错误并从OpenJDK 1.6.0_30升级到Oracle JDK 1.7.0_51,问题消失了(至少看起来如此,在过去4小时内使用的堆没有增长)。 我们不记得finalize方法有任何变化,我们也没有升级任何库,在那段时间里只有很小的发展。 问题不会在我们的测试服务器上重现,具有相同的配置,除了它是64位JVM而生产服务器是32位。 问题是:对象未完成的原因是什么, Finalizer线程等待下一个对象? 我们是否正确分析了堆转储? 谢谢你的所有答案。

幻影参考对象

幻影参考用于验尸操作。 Java规范规定,在清除幻像引用本身之前,不会释放幻像引用的对象 。 我的问题是:此function(对象未解除分配)的用途是什么? (我提出的唯一想法是允许本机代码对对象进行事后清理,但这并不是很有说服力)。

来自Object类型的方法finalize()是不可见的?

我在我编写的类的main方法中尝试了以下代码: public static void main(String[] args){ … Object s = new Object(); s.finalize(); … } 然而,日食给了我一个提示 The method finalize() from the type Object is not visible 我很困惑,因为Object类型有一个受保护的finalized方法,它应该是自己可见的? 反正我错了吗?

如何在Java中标记为最终化的对象(以便第二次不调用finalize方法)?

主要问题是在主题中,但让我展示我对Java中的最终化过程的看法,以便我可以再问你一点。 那么gc通过标记所有活动对象来启动垃圾收集。 当所有可到达的对象都标记为“活动”时。 所有其他对象都无法访问。 下一步是检查每个无法到达的对象,并确定它是否可以立即进行清理,或者应该首先完成。 如果对象的finalize方法有一个主体,那么gc会想到下一个方法,那么这个对象是可以最终确定的,应该最终确定; 如果对象的finalize方法有一个空体(protected void finalize(){})那么它不能最终化并且现在可以被gc清理。 (我是对的吗?) 所有可终结的对象将被放入同一队列中,以便稍后逐一完成。 据我所知,可终结的对象可以花费大量时间放在队列中,同时等待轮到它完成。 这可能发生,因为通常只有一个名为Finalizer的线程从队列中获取对象并调用它们的finalize方法,当我们在某个对象的finalize方法中有一些耗时的操作时,队列中的其他对象将等待很长时间才能完成。 好的,当一个对象完成后,它被标记为FINALIZED并从队列中删除。 在下一个垃圾收集过程中,收集器将看到此对象无法访问(再次)并且具有非空的finalize方法(再次),因此该对象应该被放入队列中(再次) – 但它不会因为收集器以某种方式看到这个对象被标记为FINALIZED。 (这是我的主要问题:这个对象被标记为FINALIZED的方式,收集器如何知道该对象不应该再次定型?)

如何确保始终调用finalize()(在Java练习中思考)

我正在慢慢地完成Bruce Eckel的Thinking in Java第4版 ,以下问题让我难过: 使用finalize()方法创建一个打印消息的类。 在main()中,创建一个类的对象。 修改上一个练习,以便始终调用finalize()。 这是我编码的: public class Horse { boolean inStable; Horse(boolean in){ inStable = in; } public void finalize(){ if (!inStable) System.out.print(“Error: A horse is out of its stable!”); } } public class MainWindow { public static void main(String[] args) { Horse h = new Horse(false); h = new Horse(true); […]

Java并手动执行finalize

如果我从程序代码中调用一个对象的finalize() ,那么当垃圾收集器处理这个对象时, JVM是否仍会再次运行该方法? 这将是一个近似的例子: MyObject m = new MyObject(); m.finalize(); m = null; System.gc() 显式调用finalize()会使JVM的垃圾收集器不在对象m上运行finalize()方法吗?