views:

543

answers:

6

Please help me

How to prevent an object from getting garbage collected

is there any approaches by finalize or phantom reference and is there any other approaches?

UPDATED:I was asked a ques in an interview he was referring something can be done in finalize()

+12  A: 

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.
  }
Tobias
Is there any way it can be done in finalize method
Rahul Garg
You can provoke other objects to store a new reference to your object. Note, however, that finalize is called at most once for any given object, so it won't get finalized again when the collector determines that it can be collected again.
Tobias
"(It will leave colleagues like me yelling WTF!? ;)" Yes i knw but it was ques asked to me by an interviewer so i dont have a any idea why he asked me this question :)
Rahul Garg
Maybe he wanted to see if you know what happens when you create a new reference in a finalizer (intentionally or not) and whether finalize() would get called again.
Tobias
+3  A: 

If there is still a reference to the object, it won't get garbage collected. If there aren't any references to it, you shouldn't care.

In other words - the garbage collector only collects garbage. Let it do its job.

Thomas Owens
in other, other words - don't use finalize() to play tricks on the collector
matt b
A: 

I believe there is a pattern out there for this. Not sure if it the factory pattern. But you have one object that creates all your objects and holds a reference to them. When you are finished with them, you de-reference them in the factory, making the call explicit.

Zoidberg
+2  A: 

I suspect what you might be referring to is if your finalize method stashes away a reference to the object being finalized. In this case (if my reading of the Java Language Spec is correct) the finalize method will never be re-run, but the object will not yet be garbage collected.

This is not the sort of thing one does in real life, except possibly by accident!

Simon Nickerson
+2  A: 

This sounds like one of those interview-only-time-you'll-see-it questions. finalize() is run when your object is getting garbage collected, so it'd be pretty perverse to put something in there to prevent collection. Normally you just hold a reference and that's all you need.

I'm not even sure what would happen if you'd create a new reference for something in the finalizer - since the garbage collector's already decided to collect it would you then end up with a null ref? Seems like a poor idea, in any case. e.g.

public class Foo {
   static Foo reference;
  ...
  finalize (){ 
     reference = this; 
  }
}

I doubt this would work, or it might work but be dependant on the GC implenetation, or be "unspecified behavior". Looks evil, though.

Steve B.
+2  A: 

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 call 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.

CPerkins