Re: SoftReference operation synchronization detail




<stamenkov@xxxxxxxxx> wrote in message news:1149097872.124662.211670@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
/Oliver Wong/:

Note that the reference called "cache" won't
magically turn into null behind your back. It's only the referent within the
SoftReference which may become null (which is why get() sometimes returns
null). So depending on the design of the rest of your code, the check for
cache != null might be unnescessary.

I haven't used the Reference classes up to now and seems I haven't
quite understood the description
<http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ref/SoftReference.html>:

Suppose that the garbage collector determines at a certain point in
time that an object is softly reachable. At that time it may choose
to clear atomically all soft references to that object...

The "choose to clear all soft references" part now I understand as
clear the references to the objects those Reference objects hold,
right?

But my main concern was because of some test of mine (not clear enough
thought) while playing with those Reference classes - I've got 'null'
values for the Reference variables themselves, after I have initialized
them. And reading further into the description:

... At the same time or at some later time it will enqueue those
newly-cleared soft references...

I don't understand how are the references processed from those queues,
given the they have already been cleared, but I've speculated that
process might have cleared my Reference variables, somehow. It is quite
possible I haven't overseen something, too.

That sounds most logical, but again: a Reference variable is never
cleared automatically?

First of all, we should clear up some terminology and basic concepts. Java has variables which have values. These values are sometimes primitives: e.g. when you have a variable of type int, then the value of the variable is the value of that int itself, such as the value 3. Other times, the variables act as references to objects. They "point" to the address in memory where an object is located. So for example, with this code snippet:

<code>
Foo a;
Foo b;
a = new Foo();
b = a;
</code>

You've got 2 variables, but only 1 object. Both variables point, or refer to, the same object. The variables have names. There's a variable call "a", and a variable called "b". Objects don't have names.

Objects have classes. SoftReference is a class. So you can have an object of type SoftReference. Consider now the following code:

<code>
SoftReference cache = new SoftReference(new Foo());
</code>

There are 2 objects and 1 variable. There's an instance of Foo, an instance of SoftReference, and a variable called "cache".

Cache will never "magically" become null. If you want cache to be null, you (or some other code) has to explicitly set it to null. So this following code snippet will always print "Hello world!":

<code>
SoftReference cache = new SoftReference(new Foo());
if (cache == null) {
System.out.println("This should never happen.");
} else {
System.out.println("Hello world!");
}
</code>

However, this code may sometimes print "Hello world!", sometimes print "Goodbye world!":

<code>
SoftReference cache = new SoftReference(new Foo());
if (cache.get() == null) {
System.out.println("Goodbye world!");
} else {
System.out.println("Hello world!");
}
</code>

See http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ref/package-summary.html#reachability

The SoftReference object in the code above is strongly reachable. Why? Because you can directly reach it using the variable called "cache". So the SoftReference object itself will not get garbage collected. However, the Fooobject is softly reachable. That is, it is not strongly reachable (since you don't have a variable which points to it), but you DO have a SoftReference which holds it.

(This next part starts talking about underlying implementation. It makes a bunch of simplifying assumptions, like avoiding the whole concept of "weakly reachable" and "phantom reachable" and might not reflect what the JVM is "really" doing under the covers, but hopefully it'll still help you understand the external observable behaviour.)

So the garbage collector may decide it wants to collect that Foo object. The first step in doing so is that it will tell the SoftReference to release it. Once that happens, whenever you call the .get() method on the SoftReference object, that method will return null. However, the Foo object has not yet been garbage collected. It's just floating around in memory somewhere, with no way to access it.

Now, the garbage collector can garbage collect the Foo object, without worrying about deleting an object while it's still being used. It doesn't have to worry, because the Foo object is unreachable. There's no strong-references to it, and there's no soft-references to it either.

- Oliver

.



Relevant Pages

  • Re: Weak references - I must be missing something...
    ... > they do not seem to solve a common memory problem we have. ... > but we don't want to pay the cost of putting them to disk unless it is ... The getmethod on the Reference object will always return ... A SoftReference is eligible to be put on its ReferenceQueue ...
    (comp.lang.java.programmer)
  • Re: Weak references - I must be missing something...
    ... > WeakReference. ... > A SoftReference is eligible to be put on its ReferenceQueue ... > object (which makes it a strong reference again). ... This is what I thought too, but according to the Java API ...
    (comp.lang.java.programmer)
  • Re: Implementing caches that may be cleared if heap space shrinks away
    ... creating a subclass of SoftReference that adds the value key as a ... property of the reference, keeping the references in a reference ... Whenever get or put is called on the cache, ... reference queue removing the collected values from the cache, ...
    (comp.lang.java.programmer)
  • Re: Implementing caches that may be cleared if heap space shrinks away
    ... directly from SoftReference and overriding the clearmethod. ... So what's the right way to implement a cache in Java? ... property of the reference, keeping the references in a reference ... reference queue removing the collected values from the cache, ...
    (comp.lang.java.programmer)
  • Re: Write-to-disk cache via WeakReferences?
    ... You could add size as you traverse. ... For a start, every object will reference it's class, which will reference it's class loader, the class loader's ancestors, all the classes loaded by those loaders and all the objects those classes reference. ... It doesn't cost anything to reclaim an object. ... but you have to call get on the SoftReference itself to mark as a use). ...
    (comp.lang.java.programmer)