diff --git a/xdocs/guide.xml b/xdocs/guide.xml index 26fb81d..679c801 100644 --- a/xdocs/guide.xml +++ b/xdocs/guide.xml @@ -623,9 +623,10 @@ held in LogFactory's static hashtable.

Beginning with JCL 1.1, LogFactory caches factory implementations in a -"WeakHashtable". This class is similar to java.util.WeakHashMap in that it holds a -WeakReference to each key's value, thus allowing classloaders to be GC'd -even if LogFactory.release() is never invoked. +"WeakHashtable". This class is similar to java.util.WeakHashMap in +that it holds a WeakReference to each key (but a strong reference +to each value), thus allowing classloaders to be GC'd even if +LogFactory.release() is never invoked.

Because WeakHashtable depends on JDK 1.3+ features, it is dynamically @@ -633,29 +634,26 @@ loaded depending on the JVM version; when commons-logging is run on java version prior to 1.3 the code defaults to a standard Hashtable instead.

-In a particular usage scenario, WeakHashtable alone will -be insufficent to allow garbage collection of a classloader without a call to -release. If the abstract class LogFactory is -loaded by a parent classloader and a concrete subclass implementation of -LogFactory is loaded by a child classloader, the concrete -implementation will have a strong reference to the child classloader via the -chain getClass().getClassLoader(). The WeakHashtable -will have a strong reference to the LogFactory implementation as -one of the keys in its map (only values can use weak references). This chain -of references will prevent collection of the child classloader. +If a custom LogFactory implementation is used, however, then a +WeakHashtable alone can be insufficent to allow garbage collection +of a classloader without a call to release. If the abstract class +LogFactory is loaded by a parent classloader and a concrete +subclass implementation of LogFactory is loaded by a child +classloader, the WeakHashtable's key is a weak reference to the TCCL (child +classloader), but the value is a strong reference to the LogFactory instance, +which in turn contains a strong reference to its class and thus loading +classloader - the child classloader. This chain of strong references prevents +the child loader from being garbage collected.

-Such a situation would typically only occur if commons-logging.jar were -loaded by a parent classloader (e.g. a server level classloader in a -servlet container) and a custom LogFactory implementation were -loaded by a child classloader (e.g. a web app classloader). If use of -a custom LogFactory subclass is desired, ensuring that the -custom subclass is loaded by the same classloader as LogFactory +If use of a custom LogFactory subclass is desired, ensuring that +the custom subclass is loaded by the same classloader as LogFactory will prevent problems. In normal deployments, the standard implementations of LogFactory found in package org.apache.commons.logging.impl will be loaded by the same classloader that loads LogFactory itself, so use of the standard LogFactory implementation -should not pose problems. +should not pose problems. Alternatively, use the provided ServletContextCleaner +to ensure this reference is explicitly released on webapp unload.