Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would say that since the Java Specification doesn't tell how the finalize method must be invoked (just that it must be invoked, before the object is garbage collected), the behaviour is implementation specific.</p> <p>The spec doesn't rule out having multiple threads running the process, but doesn't require it:</p> <blockquote> <p>It is important to note that many finalizer threads may be active (this is sometimes needed on large shared memory multiprocessors), and that if a large connected data structure becomes garbage, all of the finalize methods for every object in that data structure could be invoked at the same time, each finalizer invocation running in a different thread.</p> </blockquote> <p>Looking at the sources of the JDK7, the <code>FinalizerThread</code> keeps the queue of objects scheduled for finalization (actually objects are added to the queue by the GC, when proven to be unreachable - check <code>ReferenceQueue</code> doc):</p> <pre><code>private static class FinalizerThread extends Thread { private volatile boolean running; FinalizerThread(ThreadGroup g) { super(g, "Finalizer"); } public void run() { if (running) return; running = true; for (;;) { try { Finalizer f = (Finalizer)queue.remove(); f.runFinalizer(); } catch (InterruptedException x) { continue; } } } } </code></pre> <p>Each object is removed from the queue, and <code>runFinalizer</code> method is run on it. Check is done if the finalization had run on the object, and if not it is being invoked, as a call to a native method <code>invokeFinalizeMethod</code>. The method simply is calling the <code>finalize</code> method on the object:</p> <pre><code>JNIEXPORT void JNICALL Java_java_lang_ref_Finalizer_invokeFinalizeMethod(JNIEnv *env, jclass clazz, jobject ob) { jclass cls; jmethodID mid; cls = (*env)-&gt;GetObjectClass(env, ob); if (cls == NULL) return; mid = (*env)-&gt;GetMethodID(env, cls, "finalize", "()V"); if (mid == NULL) return; (*env)-&gt;CallVoidMethod(env, ob, mid); } </code></pre> <p>This should lead to a situation, where the objects get queued in the list, while the <code>FinalizerThread</code> is blocked on the faulty object, which in turn should lead to <code>OutOfMemoryError</code>.</p> <p>So to answer the original question:</p> <blockquote> <p>what will the Finalizer thread do if there is a infinite loop or deadlock in the Java finalize method.</p> </blockquote> <p>It will simply sit there and run that infinite loop until <code>OutOfMemoryError</code>.</p> <pre><code>public class FinalizeLoop { public static void main(String[] args) { Thread thread = new Thread() { @Override public void run() { for (;;) { new FinalizeLoop(); } } }; thread.setDaemon(true); thread.start(); while (true); } @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("Finalize called"); while (true); } } </code></pre> <p>Note the "Finalize called" if printed only once on the JDK6 and JDK7.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload