Class WeakHashtable
- All Implemented Interfaces:
Serializable
,Cloneable
,Map
Hashtable
to use WeakReference
's
to hold its keys thus allowing them to be reclaimed by the garbage collector.
The associated values are retained using strong references.
This class follows the semantics of Hashtable
as closely as
possible. It therefore does not accept null values or keys.
Note:
This is not intended to be a general purpose hash table replacement.
This implementation is also tuned towards a particular purpose: for use as a replacement
for Hashtable
in LogFactory
. This application requires
good liveliness for get
and put
. Various tradeoffs
have been made with this in mind.
Usage: typical use case is as a drop-in replacement
for the Hashtable
used in LogFactory
for J2EE environments
running 1.3+ JVMs. Use of this class in most cases (see below) will
allow class loaders to be collected by the garbage collector without the need
to call LogFactory.release(ClassLoader)
.
org.apache.commons.logging.LogFactory
checks whether this class
can be supported by the current JVM, and if so then uses it to store
references to the LogFactory
implementation it loads
(rather than using a standard Hashtable instance).
Having this class used instead of Hashtable
solves
certain issues related to dynamic reloading of applications in J2EE-style
environments. However this class requires Java 1.3 or later (due to its use
of WeakReference
and associates).
And by the way, this extends Hashtable
rather than HashMap
for backwards compatibility reasons. See the documentation
for method LogFactory.createFactoryStore
for more details.
The reason all this is necessary is due to a issue which
arises during hot deploy in a J2EE-like containers.
Each component running in the container owns one or more class loaders; when
the component loads a LogFactory instance via the component class loader
a reference to it gets stored in the static LogFactory.factories member,
keyed by the component's class loader so different components don't
stomp on each other. When the component is later unloaded, the container
sets the component's class loader to null with the intent that all the
component's classes get garbage-collected. However there's still a
reference to the component's class loader from a key in the "global"
LogFactory
's factories member! If LogFactory.release()
is called whenever component is unloaded, the class loaders will be correctly
garbage collected; this should be done by any container that
bundles commons-logging by default. However, holding the class loader
references weakly ensures that the class loader will be garbage collected
without the container performing this step.
Limitations: There is still one (unusual) scenario in which a component will not be correctly unloaded without an explicit release. Though weak references are used for its keys, it is necessary to use strong references for its values.
If the abstract class LogFactory
is
loaded by the container class loader but a subclass of
LogFactory
[LogFactory1] is loaded by the component's
class loader and an instance stored in the static map associated with the
base LogFactory class, then there is a strong reference from the LogFactory
class to the LogFactory1 instance (as normal) and a strong reference from
the LogFactory1 instance to the component class loader via
getClass().getClassLoader()
. This chain of references will prevent
collection of the child class loader.
Such a situation occurs when the commons-logging.jar is
loaded by a parent class loader (e.g. a server level class loader in a
servlet container) and a custom LogFactory
implementation is
loaded by a child class loader (e.g. a web app class loader).
To avoid this scenario, ensure
that any custom LogFactory subclass is loaded by the same class loader as
the base LogFactory
. Creating custom LogFactory subclasses is,
however, rare. The standard LogFactoryImpl class should be sufficient
for most or all users.
- Since:
- 1.1
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static final class
Deprecated.Entry implementationprivate static final class
Deprecated.Wrapper giving correct symantics for equals and hash codeprivate static final class
Deprecated.WeakReference subclass that holds a hard reference to an associatedvalue
and also makes accessible the Referenced object holding it. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate int
Deprecated.Counter used to control how often we purge gc'd entries.private static final int
Deprecated.The maximum number of times put() or remove() can be called before the map will be purged of all cleared entries.private static final int
Deprecated.The maximum number of times put() or remove() can be called before the map will be purged of one cleared entry.private final ReferenceQueue
Deprecated.ReferenceQueue we check for GC'd keys.private static final long
Deprecated.Serializable version identifier. -
Constructor Summary
ConstructorsConstructorDescriptionDeprecated.Constructs a WeakHashtable with the Hashtable default capacity and load factor. -
Method Summary
Modifier and TypeMethodDescriptionboolean
containsKey
(Object key) Deprecated.elements()
Deprecated.entrySet()
Deprecated.Deprecated.boolean
isEmpty()
Deprecated.keys()
Deprecated.keySet()
Deprecated.private void
purge()
Deprecated.Purges all entries whose wrapped keys have been garbage collected.private void
purgeOne()
Deprecated.Purges one entry whose wrapped key has been garbage collected.Deprecated.void
Deprecated.protected void
rehash()
Deprecated.Deprecated.int
size()
Deprecated.toString()
Deprecated.values()
Deprecated.Methods inherited from class java.util.Hashtable
clear, clone, compute, computeIfAbsent, computeIfPresent, contains, containsValue, equals, forEach, getOrDefault, hashCode, merge, putIfAbsent, remove, replace, replace, replaceAll
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDDeprecated.Serializable version identifier.- See Also:
-
MAX_CHANGES_BEFORE_PURGE
private static final int MAX_CHANGES_BEFORE_PURGEDeprecated.The maximum number of times put() or remove() can be called before the map will be purged of all cleared entries.- See Also:
-
PARTIAL_PURGE_COUNT
private static final int PARTIAL_PURGE_COUNTDeprecated.The maximum number of times put() or remove() can be called before the map will be purged of one cleared entry.- See Also:
-
queue
Deprecated.ReferenceQueue we check for GC'd keys. -
changeCount
private int changeCountDeprecated.Counter used to control how often we purge gc'd entries.
-
-
Constructor Details
-
WeakHashtable
public WeakHashtable()Deprecated.Constructs a WeakHashtable with the Hashtable default capacity and load factor.
-
-
Method Details
-
containsKey
Deprecated.- Specified by:
containsKey
in interfaceMap
- Overrides:
containsKey
in classHashtable
- See Also:
-
elements
Deprecated. -
entrySet
Deprecated. -
get
Deprecated. -
isEmpty
public boolean isEmpty()Deprecated. -
keys
Deprecated. -
keySet
Deprecated. -
purge
private void purge()Deprecated.Purges all entries whose wrapped keys have been garbage collected. -
purgeOne
private void purgeOne()Deprecated.Purges one entry whose wrapped key has been garbage collected. -
put
Deprecated. -
putAll
Deprecated. -
rehash
protected void rehash()Deprecated. -
remove
Deprecated. -
size
public int size()Deprecated. -
toString
Deprecated. -
values
Deprecated.
-