3

I was reading about WeakReference and SoftReference.

Found the below:

WeakReference:

Counter counter = new Counter(); // strong reference - line 1
WeakReference<Counter> weakCounter = new WeakReference<Counter>(counter); //weak reference
counter = null; // now Counter object is eligible for garbage collection

Soft Reference:

Counter prime = new Counter(); // prime holds a strong reference - line 2
SoftReference<Counter> soft = new SoftReference<Counter>(prime) ; //soft reference variable has SoftReference to Counter Object created at line 2
prime = null; // now Counter object is eligible for garbage collection but only be collected when JVM absolutely needs memory

Here, anyways I am assigning null to the strong reference counter and prime and they are eligible for garbage collection and will be garbage collected when next GC cycle will run.

How is WeakReference / SoftReference impacting/assisting the garbage collection here?

UPDATE:

In the program below:

public class WeakReferenceSample {
    public static void main(String[] args) {
        HelloWorld helloWorld = new HelloWorld();
        WeakReference<HelloWorld> helloWorldReference = new WeakReference<>(helloWorld);
        helloWorld = null;
        System.out.println(helloWorld);
        System.out.println(helloWorldReference.get());
        System.gc();
        System.out.println(helloWorldReference.get());
    }
}

Even after changing helloWorld reference to null, my first System.out.println(helloWorldReference.get());is printing the object value and not null. After System.gc(), the second time it is printing as null. How this works internally as both the helloWorld reference and helloWorldReference reference point to the same HelloWorld object.

Sample output:

null
HelloWorld@2503dbd3
null

Proof: If I DO NOT assign null to helloWorld reference, then, both the helloWorld reference and helloWorldReference reference point to the same HelloWorld object.

HelloWorld@2503dbd3
HelloWorld@2503dbd3
HelloWorld@2503dbd3

Confused with how it works internally? Earlier I was thinking like it clones the object and then weak references it, but from the output, it does not look like.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
vijayinani
  • 2,548
  • 2
  • 26
  • 48

2 Answers2

2

Long story short

None of the objects has a strong reference so objects are eligible for garbage collection. But different reference types will determine how the garbage collector will prioritize the objects' garbage collection.

The actual details of what happens during a garbage collection cycle can differ based on different parameters. Some of these parameters are the following:

  • JRE/VM version
  • Actual garbage collection algorithm selected
  • Available memory in the system
  • System resources

In principle the garbage collector tries to be fast and effective in order not to affect performance in the long and short run and at the same time make sure that there is enough memory available.

So during the garbage collection the garbage collector will try to free up some memory by garbage collecting some objects. Garbage collector will eventually determine how many memory it will free up and which objects to garbage collect in order to do it. The garbage collector does not necessarily garbage collect all eligible objects at each run.

So we can say that the objects that are eligible for garbage collection will be garbage collected with different priorities. So the garbage collection priority will be the following:

  1. Unreferenced objects have the highest priority of being garbage collected.
  2. Weak referenced objects are the next more eligible objects to be garbage collected.
  3. Soft referenced objects are the next more eligible objects to be garbage collected.

Based on this prioritization the object with a weak reference is likely to be garbage collected more eagerly than a soft referenced object. However the decision and responsibility of when each object will be garbage collected is taken only by the garbage collector.

The definition speaks about priorities (eagerness) and not precise rules so one can expect to observe that: In the long run (and if observed in many different JREs and under different circumstances) a Weakly Referenced object tends to be garbage collected before a Soft Referenced object.

"A soft reference is exactly like a weak reference, except that it is less eager to throw away the object to which it refers." quote from this answer here; Soft vs Weak reference Java also includes Phantom references which is a related concept. Phantom References

Update following the question's update:

In your first example:

null This is expected as it is a strong reference in helloWorld variable which has been explicitly set to null.

HelloWorld@2503dbd3 Weak reference in helloWorldReference variable has not been garbage collected yet, so it is still there. However since this is the only reference to the object, it is eligible for garbage collection. It can happen that this is also printed as null if you run this example many times. You can see it if you run another thread that consumes too much memory.

null Weak reference in helloWorldReference variable has been garbage collected. It can also be the case that this object is not null depending on the garbage collector running. Among others the garbage collector can depend on the VM and the arguments the VM was given before started. See also the javadoc of System.gc.

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

Notice the words in bold. They hint to the fact that this method does not always have the same result. Calling this method is a suggestion to the VM which will act in a best effort basis.

In your second example:

HelloWorld@2503dbd3 Strong reference in helloWorld variable exists

HelloWorld@2503dbd3 Weak reference in helloWorldReference variable has not been garbage collected yet, since there is already a strong reference to this object. The object is not eligible for garbage collection.

HelloWorld@2503dbd3 Weak reference in helloWorldReference variable retrieves the object as it has not been garbage collected. Since there is already a Strong reference to the object the object will never be garbage collected.

Spyros K
  • 2,480
  • 1
  • 20
  • 37
  • Nice observation. Thank you for finding this. Yes, they were written in reverse. Contradicting the rest of the answer. – Spyros K Aug 13 '18 at 15:04
1

WeakReferences and SoftReferences do not “assist” the garbage collector, though they provide a hint as to whether or not the reference should be kept around if possible. If the only reference to an object is weak or soft, the GC can collect the object. However, an object with SoftReferences is generally not garbage collected unless the JVM needs the memory. They are good for things like caches.

Jeff Storey
  • 56,312
  • 72
  • 233
  • 406