olshevski
olshevski

Reputation: 5010

Can object be garbage collected between two subsequent calls to WeakReference.get()?

I sometimes see the code of this kind in some library APIs and just in someone's code:

class SomeClass {

    private WeakReference<SomeObject> objectWeakReference; // initialized elsewhere

    public boolean isObjectAttached() {
        return objectWeakReference.get() != null;
    }

    public SomeObject getObject() {
        return objectWeakReference.get();
    }

}

and

public void checkAndGetWeakReference() {
    SomeClass someClass = new SomeClass();
    if (someClass.isObjectAttached()) {
        someClass.getObject().doSomethingDirectlyOnReturnedObject(); // can the returned reference be null here ?
    }
}

And I'm always worried if there could be NullPointerException once in a blue moon, assuming there are no strong reference to the underlying object at this point.

I don't really know when exactly Garbage Collector can start deleting objects from memory and how does it correlate with the basic thread flow.

It would be nice if someone can shed the light on this particular subject and/or provide some information about the topic.

P.S. I would personally get reference only once and assign it to strong reference. The point of the question is to get some proof the code above is wrong.

Upvotes: 2

Views: 254

Answers (4)

Harshit Thacker
Harshit Thacker

Reputation: 112

I would like to add something to all answers.

Your object can be null when you call below method :

public SomeObject getObject() {
        return objectWeakReference.get();
    }

about garbage collection of this object. If you do something like below :

public static void main(String args[]) {
     SomeClass oSomeClass = new SomeClass();

     // this one is strong reference "obj"
     // this object can be null. Best practice is to null check before you use it.
    // Or i will suggest to call isObjectAttached() method before you use it
     Object obj = oSomeClass.getObject(); 
}

When you do obj = null; somewhere in code after above statement.

This object memory is available for garbage collection. Whenever JVM feels to clean memory. Yes it can collect this object.

Regarding proof of code you are asking.

public boolean isObjectAttached() {
        return objectWeakReference.get() != null;
    }

This method is made for you to check whether this object is present in memory or it has a valid reference for you.

If it returns true you will never get nullpointer exception.

but if you are not using this method i will suggest to use null check always before you use your object.

Hope I am on right direction and making some sense in my answer. Please respond accordingly.

We all are here to learn ;-) Enjoy Java, OOP concepts.

Upvotes: 0

Mohan Raj
Mohan Raj

Reputation: 1132

Garbage collector internally has its heuristics to collect soft/weak/phantom references. It will not collect those objects in subsequent GC calls. It tracks these objects until it reaches the threshold of that heuristics, GC is not allowed to collect these references.

Upvotes: -3

Durandal
Durandal

Reputation: 20069

The whole point of the WeakReference (and SoftReference as well) is that the referred object may be gc'd at any time no strong reference to the object exists.

Since there exists no strong reference when isObjectAttached() returns, yes it can be garbage collected before it actually gets to execute getObject(). The whole idom is faulty for this use case.

The only safe way is to first get the reference (e.g. to a local variable) and then check it against null. The object can then not be garbage collected in that case, because a local variable is a strong reference.

Upvotes: 5

Harshit Thacker
Harshit Thacker

Reputation: 112

As per java doc. You should not rely on Garbage collector. Its not sure when it will be executed. Though you are trying explicitly System.gc()

Its always been a lowest priority for JVM for garbage collector. When JVM is free or when your program is around to ran out of memory it can execute GC.

In other case when your program will exit. It will be garbage collected before it is flushed out of JVM memory.

Please refer javadoc for detailed explanation for GC.

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Upvotes: 0

Related Questions