How to prevent an object from getting garbage collected?

The trick answer your interviewer was looking for is probably that he wants you to know that you can prevent garbage collection from removing an object by forcing a memory leak.

Obviously, if you keep a reference to the object in some long-lived context, it won't be collected, but that's not what the OP's recruiter asked about. That's not something which happens in the finalize method.

What you can do to prevent garbage collection from within the finalize method is to write an infinite loop, in which you call Thread.yield();(presumably to keep an empty loop from being optimized away):

@Override
protected void finalize() throws Throwable { 
    while (true) { 
        Thread.yield(); 
    } 
} 

My reference here is an article by Elliot Back, in which describes forcing a memory leak by this method.

Just another way in which finalize methods are evil.


Hold a reference. If your object is getting collected prematurely, it is a symptom that you have a bug in the design of your application.

The garbage collector collects only objects to which there is no reference in your application. If there is no object that would naturally reference the collected object, ask yourself why it should be kept alive.

One usecase in which you typically have no references, but want to keep an object is a singleton. In this case, you could use a static variable. One possible implementation of a singleton would look like this:

public class Singleton {
  private static Singleton uniqueInstance;

  private Singleton() {
    }

  public static synchronized Singleton getInstance() {
    if (uniqueInstance == null) {
      uniqueInstance = new Singleton();
    }
    return uniqInstance;
  }
}

Edit: Technically, you can store a reference somewhere in your finalizer. This will prevent the object from being collected until the collector determines again that there are no more references. The finalizer will only be called at most once, however, so you must ensure that your object (including its superclasses) need not be finalized after the first collection. I would advise you, however, not to use this technique in actual programs. (It will leave colleagues like me yelling WTF!? ;)

  protected void finalize() throws Throwable {
    MyObjectStore.getInstance().store(this);
    super.finalize(); // questionable, but you should ensure calling it somewhere.
  }