leif 02/02/21 23:29:22
Modified: src/java/org/apache/avalon/excalibur/component
ExcaliburComponentManager.java
Log:
Fix a memory leak being caused by mappings between Components
and ComponentHandlers not being removed.
Revision Changes Path
1.19 +24 -19
jakarta-avalon-excalibur/src/java/org/apache/avalon/excalibur/component/ExcaliburComponentManager.java
Index: ExcaliburComponentManager.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/java/org/apache/avalon/excalibur/component/ExcaliburComponentManager.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- ExcaliburComponentManager.java 20 Feb 2002 06:26:42 -0000 1.18
+++ ExcaliburComponentManager.java 22 Feb 2002 07:29:22 -0000 1.19
@@ -36,7 +36,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Paul Russell</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Ryan Shaw</a>
- * @version CVS $Revision: 1.18 $ $Date: 2002/02/20 06:26:42 $
+ * @version CVS $Revision: 1.19 $ $Date: 2002/02/22 07:29:22 $
* @since 4.0
*/
public class ExcaliburComponentManager
@@ -55,24 +55,19 @@
/** The classloader used for this system. */
private final ClassLoader m_loader;
- /** The application context for components
- */
+ /** The application context for components */
private Context m_context;
- /** Static component mapping handlers.
- */
+ /** Static component mapping handlers. */
private final BucketMap m_componentMapping = new BucketMap();
- /** Static component handlers.
- */
+ /** Used to map roles to ComponentHandlers. */
private final BucketMap m_componentHandlers = new BucketMap();
- /** RoleInfos.
- */
+ /** RoleInfos. */
private RoleManager m_roles;
- /** LogKitManager.
- */
+ /** LogKitManager. */
private LogKitManager m_logkit;
/** Is the Manager disposed or not? */
@@ -377,7 +372,12 @@
throw new ComponentException( message, e );
}
+ // Add a mapping between the component and its handler.
+ // In the case of a ThreadSafeComponentHandler, the same component
will be mapped
+ // multiple times but because each put will overwrite the last,
this is not a
+ // problem. Checking to see if the put has already been done would
be slower.
m_componentMapping.put(component, handler);
+
return component;
}
@@ -501,6 +501,10 @@
{
return;
}
+
+ // The m_componentMapping BucketMap itself is threadsafe, and
because the same component
+ // will never be released by more than one thread, this method does
not need any
+ // synchronization around the access to the map.
final ComponentHandler handler =
(ComponentHandler)m_componentMapping.get( component );
@@ -519,14 +523,15 @@
}
}
- // RBS: I don't think we should be removing component-->handler
- // mappings here, because if the Component is threadsafe, and
- // it has had multiple lookups, then the first release will
- // remove the component from the mapping, and subsequent releases
- // will never call handler.put(), which is bad for keeping track
- // of whether components are being used.
- //
- // m_componentMapping.remove( component );
+ // ThreadSafe components will always be using a
ThreadSafeComponentHandler,
+ // they will only have a single entry in the m_componentMapping
map which
+ // should not be removed until the ComponentManager is
disposed. All
+ // other components have an entry for each instance which
should be
+ // removed.
+ if ( !( handler instanceof ThreadSafeComponentHandler ) )
+ {
+ m_componentMapping.remove( component );
+ }
}
else if ( null != m_parentManager)
{
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>