Adam said:
People use it to implement 'cache memory'.
If you have some objects that are reused
often in your application, and their
construction is expensive, and there
are too many of them to keep them all
in memory -
- you use WeakHashMap.
Put there the object which is not currently
used. When this object is needed - get it out
of the map. For most of the time most of those
objects will be staying in the map.
The trick is that they are not held
directly, but through WeakReferences.
So if it gets really 'crowded', when we are running
out of memory, gc will be allowed to collect
them.
This isn't really accurate. WeakHashMap uses WeakReference, not
SoftReference, for one thing. That means the garbage collector will
make no more effort to keep objects in memory than it would have made if
there were no references to them at all. Second, and most importantly,
it's the *keys* that are kept with weak references; the objects are
considered strongly referenced until the key becomes unreachable.
I have no idea why there's no SoftHashMap class in the Java core API
that acts as Adam wrote above. It would make sense to have around, and
I've written at least one of them. Nevertheless, they are a different
and unrelated matter.
The purpose of WeakHashMap is to provide a Map implementation that will
automatically discard objects when it's impossible to get them back out
again. As such, it must be used in situations where two objects can't
be considered equal unless they really are the same object.
As an example, I could have an application that receives task
descriptions and performs some long-term operations on their behalf.
Let's say, just for kicks, that I'm going to spawn separate threads for
each of these operations and then let them do their work, while the
first thread goes on to wait for more task descriptions. The important
bit about this architecture is that there is no single point where you
can clean up after a task; when any of the parallel threads finishes, it
may or may not be the last thread performing work for that task, and
there's no easy way to find out.
Now, let's suppose that the tasks are related enough that there are some
expensive shared computations between them. The results of these
computations, though, are valid only within that task. And let's say
we've chosen to store those computations in a global synchronized Map.
The question is this: when do we remove these cached computations from
the global Map.
WeakHashMap gives an answer: if we use some object with a unique
identity (meaning, in a nutshell, that it doesn't override the equals
method) as a key for the computations; and if that key is passed along
and shared by all the threads in a given task but never communicated
outside of the task, then as soon as all the threads exit, the key will
become unreachable (Because the WeakHashMap holds only a weak
reference). When the garbage collector realizes that the key is
unreachable, the WeakHashMap will automatically remove those
computations from the cache.
There's a use for WeakHashMap. In all honesty, though, I think there
are better designs (task-specific HashMap, for example), and I have a
hard time justifying a situation that really requires a WeakHashMap to
implement reasonably. Nevertheless, that's up to each individual
developer to decide for their own projects.
--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation