Improved javadocs for WeakHashTable. More readable explaination contributed by Simon Kitching.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/logging/trunk@156689 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -23,10 +23,14 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Implementation of <code>Hashtable</code> that uses <code>WeakReference</code>'s
|
* <p>Implementation of <code>Hashtable</code> that uses <code>WeakReference</code>'s
|
||||||
* to hold it's keys thus allowing them to be reclaimed by the garbage collector.
|
* to hold its keys thus allowing them to be reclaimed by the garbage collector.
|
||||||
* This class follows the symantics of <code>Hashtable</code> as closely as possible.
|
* The associated values are retained using strong references.</p>
|
||||||
* It therefore does not accept null values or keys.
|
*
|
||||||
* <p>
|
* <p>This class follows the symantics of <code>Hashtable</code> as closely as
|
||||||
|
* possible. It therefore does not accept null values or keys.</p>
|
||||||
|
*
|
||||||
|
* <p><strong>Note:</strong>
|
||||||
|
* This is <em>not</em> intended to be a general purpose hash table replacement.
|
||||||
* This implementation is also tuned towards a particular purpose: for use as a replacement
|
* This implementation is also tuned towards a particular purpose: for use as a replacement
|
||||||
* for <code>Hashtable</code> in <code>LogFactory</code>. This application requires
|
* for <code>Hashtable</code> in <code>LogFactory</code>. This application requires
|
||||||
* good liveliness for <code>get</code> and <code>put</code>. Various tradeoffs
|
* good liveliness for <code>get</code> and <code>put</code>. Various tradeoffs
|
||||||
@@ -34,35 +38,82 @@ import java.util.*;
|
|||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Usage:</strong> typical use case is as a drop-in replacement
|
* <strong>Usage:</strong> typical use case is as a drop-in replacement
|
||||||
* for the <code>Hashtable</code> use in <code>LogFactory</code> for J2EE enviroments
|
* for the <code>Hashtable</code> used in <code>LogFactory</code> for J2EE enviroments
|
||||||
* running 1.3+ JVMs. Use of this class <i>in most cases</i> (see below) will
|
* running 1.3+ JVMs. Use of this class <i>in most cases</i> (see below) will
|
||||||
* allow classloaders to be collected by the garbage collector without the need
|
* allow classloaders to be collected by the garbage collector without the need
|
||||||
* to call {@link org.apache.commons.logging.LogFactory#release(ClassLoader) LogFactory.release(ClassLoader)}.
|
* to call {@link org.apache.commons.logging.LogFactory#release(ClassLoader) LogFactory.release(ClassLoader)}.
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
|
* <p><code>org.apache.commons.logging.LogFactory</code> looks to see whether this
|
||||||
|
* class is present in the classpath, and if so then uses it to store
|
||||||
|
* references to the <code>LogFactory</code> implementationd it loads
|
||||||
|
* (rather than using a standard Hashtable instance).
|
||||||
|
* Having this class used instead of <code>Hashtable</code> 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 <code>java.lang.ref.WeakReference</code> and associates) and therefore cannot be
|
||||||
|
* included in the main logging distribution which supports JVMs prior to 1.3.
|
||||||
|
* And by the way, this extends <code>Hashtable</code> rather than <code>HashMap</code>
|
||||||
|
* for backwards compatibility reasons. See the documentation
|
||||||
|
* for method <code>LogFactory.createFactoryStore</code> for more details.</p>
|
||||||
|
*
|
||||||
|
* <p>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 classloaders; when
|
||||||
|
* the component loads a LogFactory instance via the component classloader
|
||||||
|
* a reference to it gets stored in the static LogFactory.factories member,
|
||||||
|
* keyed by the component's classloader so different components don't
|
||||||
|
* stomp on each other. When the component is later unloaded, the container
|
||||||
|
* sets the component's classloader to null with the intent that all the
|
||||||
|
* component's classes get garbage-collected. However there's still a
|
||||||
|
* reference to the component's classloader from the "global" <code>LogFactory</code>'s
|
||||||
|
* factories member! If <code>LogFactory.release()</code> is called whenever component
|
||||||
|
* is unloaded (as happens in some famous containers), the classloaders will be correctly
|
||||||
|
* garbage collected.
|
||||||
|
* However, holding the classloader references weakly ensures that the classloader
|
||||||
|
* will be garbage collected without programmatic intervention.
|
||||||
|
* Unfortunately, weak references are
|
||||||
|
* only available in java 1.3+, so this code only uses <code>WeakHashtable</code> if the
|
||||||
|
* class has explicitly been made available on the classpath.</p>
|
||||||
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* In a particular usage scenario, use of <code>WeakHashtable</code> alone will
|
* Because the presence of this class in the classpath ensures proper
|
||||||
* be insufficent to allow garbage collection of a classloader without a call to
|
* unload of components without the need to call method
|
||||||
* <code>release</code>. If the abstract class <code>LogFactory</code> is
|
* {@link org.apache.commons.logging.LogFactory#release(ClassLoader) LogFactory.release ClassLoader)},
|
||||||
* loaded by a parent classloader and a concrete subclass implementation of
|
* it is recommended that this class be deployed along with the standard
|
||||||
* <code>LogFactory</code> is loaded by a child classloader, the concrete
|
* commons-logging.jar file when using commons-logging in J2EE
|
||||||
* implementation will have a strong reference to the child classloader via the
|
* environments (which will presumably be running on Java 1.3 or later).
|
||||||
* chain <code>getClass().getClassLoader()</code>. The <code>WeakHashtable</code>
|
* There are no know ill effects from using this class.</p>
|
||||||
* will have a strong reference to the <code>LogFactory</code> implementation as
|
*
|
||||||
* one of the values in its map. This chain of references will prevent
|
|
||||||
* collection of the child classloader.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
* <p>
|
||||||
* Such a situation would typically only occur if commons-logging.jar were
|
* <strong>Limitations:</strong>
|
||||||
|
* 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.</p>
|
||||||
|
*
|
||||||
|
* <p> If the abstract class <code>LogFactory</code> is
|
||||||
|
* loaded by the container classloader but a subclass of
|
||||||
|
* <code>LogFactory</code> [LogFactory1] is loaded by the component's
|
||||||
|
* classloader 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 classloader via
|
||||||
|
* <code>getClass().getClassLoader()</code>. This chain of references will prevent
|
||||||
|
* collection of the child classloader.</p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Such a situation occurs when the commons-logging.jar is
|
||||||
* loaded by a parent classloader (e.g. a server level classloader in a
|
* loaded by a parent classloader (e.g. a server level classloader in a
|
||||||
* servlet container) and a custom <code>LogFactory</code> implementation were
|
* servlet container) and a custom <code>LogFactory</code> implementation is
|
||||||
* loaded by a child classloader (e.g. a web app classloader). If use of
|
* loaded by a child classloader (e.g. a web app classloader).</p>
|
||||||
* a custom <code>LogFactory</code> subclass is desired, ensuring that the
|
*
|
||||||
* custom subclass is loaded by the same classloader as <code>LogFactory</code>
|
* <p>To avoid this scenario, ensure
|
||||||
* will prevent problems. In normal deployments, the standard implementations
|
* that any custom LogFactory subclass is loaded by the same classloader as
|
||||||
* of <code>LogFactory</code> found in package <code>org.apache.commons.logging.impl</code>
|
* the base <code>LogFactory</code>. Creating custom LogFactory subclasses is,
|
||||||
* will be loaded by the same classloader that loads <code>LogFactory</code>
|
* however, rare. The standard LogFactoryImpl class should be sufficient
|
||||||
* itself, so use of the standard <code>LogFactory</code> implementations
|
* for most or all users.</p>
|
||||||
* should not pose problems.
|
*
|
||||||
*
|
*
|
||||||
* @author Brian Stansberry
|
* @author Brian Stansberry
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user