THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

// don't remember it, read it in
data = readBytesFromFile(file);
lastFile = file;
lastData = new WeakReference<byte[]>(data);


return data;
}
}


When readFile is called it first checks to see if the last file read was the same as the one being requested. If
it is, readFile retrieves the reference stored in lastData, which is a weak reference to the last array of
bytes returned. If the reference returned by get is null, the data has been garbage collected since it was last
returned and so it must be re-read. The data is then wrapped in a new WeakReference. If get returns a
non-null reference, the array has not been collected and can be returned.


If lastData were a direct, strong reference to the last data returned, that data would not be collected, even if
the invoking program had long since dropped all references to the array. Such a strong reference would keep
the object alive as long as the DataHandler object itself was reachable. This could be quite unfortunate.
Using a WeakReference allows the space to be reclaimed, at the cost of occasionally re-reading the data
from disk.


Notice that invoking get on lastData makes the byte array strongly reachable once again because its
value is bound to an active local variablea strong reference. If get returns a non-null reference there is no
possibility of the byte array being reclaimed as long as readFile is executing, or the block of code to which
readFile returns the reference is executing. That invoking code can store the reference in a reachable place
or return it to another method, thereby ensuring the data's reachability. An object can only be less than
strongly reachable when none of its references are strong. Storing a non-null reference fetched from a
reference object's get method creates a strong reference that will be treated like any other strong reference.


Weak references typically store information about an object that might be time consuming to compute but that
need not outlive the object itself. For example, if you had some complicated information built up from using
reflection on an object, you might use the java.util.WeakHashMap class, which is a hashtable for
mapping a weakly-held object to your information. If the object becomes unreachable the WeakHashMap
will clean up the associated information, which presumably is no longer useful (since the object will not be
used in any future computation because of its weak reachability). You will learn about WeakHashMap with
the rest of the collection classes in Chapter 21, specifically in Section 21.9 on page 594.


Exercise 17.2: Modify DataHandler so that lastFile is also stored weakly.


17.5.3. Reference Queues


When an object changes reachability state, references to the object may be placed on a reference queue. These
queues are used by the garbage collector to communicate with your code about reachability changes. They are
usually the best way to detect such changes, although you can sometimes poll for changes as well, by seeing if
get returns null.


Reference objects can be associated with a particular queue when they are constructed. Each of the
Reference subclasses provide a constructor of the form


publicStrengthReference(T referent, ReferenceQueue<? super T>
q)
Free download pdf