You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by robert burrell donkin <ro...@blueyonder.co.uk> on 2003/05/01 20:20:00 UTC
Re: [PATCH][collections] purging reference map entries when key is garbage collected
On Wednesday, April 30, 2003, at 05:04 PM, Craig R. McClanahan wrote:
>
>
> On Wed, 30 Apr 2003, robert burrell donkin wrote:
>
>> Date: Wed, 30 Apr 2003 13:54:01 +0100
>> From: robert burrell donkin <ro...@blueyonder.co.uk>
>> Reply-To: Jakarta Commons Developers List <commons-
>> dev@jakarta.apache.org>
>> To: Jakarta Commons Developers List <co...@jakarta.apache.org>
>> Subject: Re: [PATCH][collections] purging reference map entries when key
>> is garbage collected
>>
>> On Wednesday, April 30, 2003, at 02:20 PM, Juozas Baliuka wrote:
>>
>>>> <background>
>>>> i'm looking into per context classloader BeanUtilsBean instances. the
>>>> idea
>>>> is that each web app can have it's own isolated instances (rather
>>>> than a
>>>> singleton) return on the basis on the thread's contest classloader.
>>>> </background>
>>>
>>> Possible I do not understan a use case, but
>>> each web will have it's own isolated instances, if beanutils.jar is
>>> cloned
>>> per each WEB-INF/lib .
>>> Do you want to have "global" jar loaded by single class loader, but
>>> singletons per classLoader ?
>>
>> (i'll explain as well as i can: craig's the expert)
>>
>> beanutils used to use static utility classes. we've been moving the
>> functionality into beans (this gives greater flexibility for users). as
>> a
>> preliminary step, the static utility classes used a proper singleton.
>> this
>> means that if beanutils are loaded by the same classloader in different
>> web apps, it is possible that changes made to the beanutils settings in
>> one web app may effect another.
>>
>> threads servicing different web applications should have different
>> ContextClassLoaders so (as i understand it) by returning an instance
>> based
>> on the ContextClassLoaders of the thread making the call we should make
>> sure that different web apps get different instances. (of course, some
>> badly behaved servlet containers might confound this scheme by using
>> different classloader instances without providing a good equals method.)
>>
>>> You can use ThreadLocal, it is internaly implemented as weak map without
>>> dependancy on collections.
>>
>> AFAIK ThreadLocal can only be used to store variables associated with a
>> particular thread. if so, then this isn't really what we're looking for.
>> (i'd be glad to be corrected if i've missed something.)
>>
>
> Robert has the basics exactly right.
>
> The use case we've got is a servlet container (like Tomcat) that provides
> a class loader for each web application, plus a shared class loader that
> is the parent of all the webapp class loaders. For details on the
> architecture, see:
>
> http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html
>
> With previous beanutils code (using only the static singleton), things
> worked fine if you put commons-beanutils.jar in each webapp's /WEB-INF/lib
> directory -- each webapp got their own copy of the singleton, with no
> conflicts. However, if commons-beanutils.jar was put in a parent class
> loader (in Tomcat, by putting commons-beanutils.jar into shared/lib or
> common/lib), we ran into conflicts.
>
> The first step, as Robert points out, was to isolate the actual processing
> logic of each class into a separate class that used instance methods
> instead of the static ones (BeanUtils --> BeanUtilsBean and so on). Next,
> we need to work out the strategy of ensuring that each caller receives the
> BeanUtilsBean instance that is appropriate for their environment. Here is
> where we need to do some interesting planning.
>
> For a servlet container, using ThreadLocal is not the right answer,
> because the container will recycle each request processing thread across
> multiple webapps -- what we really want to do is allocate a BeanUtilsBean
> instance per web application. The easiest way to do that is to use the
> Thread's context class loader -- this works because the container is
> required to set the thread context class loader to point at the webapp
> class loader before invoking the servlet to process a request. Therefore,
> we should be able to use the class loader as the key to a map to keep the
> right instances.
>
> However, we probably want to provide a strategy plugin for creating
> instances -- I would advocate for the behavior described in the previous
> paragraph as the default, but other strategies certainly seem feasible as
> well for non-servlet-container environments.
i've now completed a basic prototype of a suitable system that returns an
instance on the basis of the Thread's context class loader. in order to
prevent problems with memory leaks, i need a map which holds keys with
weak references and purges entries when then key is garbage collected. the
patch i submitted adds this functionality to ReferenceMap in collections.
i'd prefer to see some more feedback from the collections team rather than
just adding my name and committing this change.
i support the idea of a strategy plugin but i think that we need to think
clearly about the design. it's going to have to act at the class level and
so is going to have to be discovery-esque (but i'd prefer not to depend on
discovery - at least until there's a stable release).
- robert
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org