8

In java the garbage collect will invoke finalize method on an object x if there's no strong reference pointing to x and x is eligible for garbage collection. What if the finalize method never terminates, would this cause a memory leak?

public class X{
  protected void finalize(){
     while(true){}
  }
}
user121196
  • 30,032
  • 57
  • 148
  • 198

4 Answers4

6

Yes it will, easy to test

public class X {

    protected void finalize() {
        while (true) {
        }
    }

    public static void main(String[] args) throws Exception {
        while (true) {
            new X();
        }
    }
}

after some time I got

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

when I removed finalize() the test never stopped. Note that it takes a while before JVM goes OOM

BTW it's enough to run this test

public class X {
    byte[] a = new byte[100 * 1000 * 1000];

    protected void finalize() {
        System.out.println();
    }

    public static void main(String[] args) throws Exception {
        while (true) {
            new X();
        }
    }
}

to break GC

Exception in thread "main" 
java.lang.OutOfMemoryError: Java heap space
    at test.X.<init>(X.java:5)
    at test.X.main(X.java:13)

comment out //System.out.println(); and it works non-stop

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • Interestingly, on mac os x, the program just terminates with no error message. I added exception handling around the while loop, but no exception was caught. I also added some output from the finalizer, just to see whether it was ever invoked, but none was shown. – Henrik Aasted Sørensen Jan 24 '13 at 11:28
  • Oops, you never know, corrected my answer as "Yes, it may ..." – Evgeniy Dorofeev Jan 24 '13 at 11:31
  • @Henrik BTW it takes a while before it goes OOM, maybe you did not wait long enough? – Evgeniy Dorofeev Jan 24 '13 at 11:48
  • @EvgeniyDorofeev: Well, it was not a matter of waiting long enough. The program simply terminated. I'm not implying that your observations are wrong. I'm just contributing my observations from running the program on my machine. – Henrik Aasted Sørensen Jan 24 '13 at 11:55
2

Yes.
Also inside finalize method if you give valid reference to object on which finalize method is invoked, Java will not garbage collect the object also will not invoke the finalize method again as it is invoked only once.

Ajinkya
  • 22,324
  • 33
  • 110
  • 161
2

Definitely.The memory will be deallocated after finalise method returns.And if your finalise never returns, momory will not get deallocated.

Google about resurrection in garbage collection and you will get various instances where finalise method does not guarantee the gc

Renjith
  • 3,274
  • 19
  • 39
0

It would block the java.lang.ref.Finalizer$FinalizerThread (The Secret Life Of The Finalizer), the instance of all classes which implement finalize method would be blocked in java.lang.ref.Finalizer.ReferenceQueue. You continue creating new object with 'finalize', memory would be exhausted by those objects which are waiting to execute finalize . If take a heap dump, you would see objects are retained by java.lang.ref.Finalizer, see below example (it's a real case). enter image description here

leef
  • 593
  • 8
  • 12