[PATCH 0/2] Class- and class loader-local storage (Bug ID #6493635)

David M. Lloyd david.lloyd at redhat.com
Fri Feb 27 19:04:55 UTC 2009


On 02/27/2009 12:52 PM, Bob Lee wrote:
> On Fri, Feb 27, 2009 at 10:40 AM, David M. Lloyd <david.lloyd at redhat.com> wrote:
>> Seems like a reasonable alternate approach, *however* I think there ought to
>> be a way to clear the reference as well, which would complicate matters a
>> little with respect to the internal data structure.
> 
> Do you have a use case?
> 
> *If* we wanted to support removals, I would do something like this:
> 
>  public class ClassLoader {
>    public Reference<?> keepReferenceTo(Object o) { ... }
>    ...
>  }
> 
> You could call clear() on the returned reference to clear the
> ClassLoader's reference. Internally, it would use some sort of CAS
> doubly-linked list.

A couple use cases, off the top of my head:

1) I've got a set of FooBars that associate with Classes; now for whatever 
reason, I want to change the FooBar that is associated with the Class.  The 
old FooBar is now completely unreferenced; keeping a reference to it is a leak.

2) I've got an application server deployment that provides some kind of 
service by class, so I stash refs on the ClassLoaders of the Classes for 
whom the service is provided.  I want to undeploy my application, but all 
those classloaders have strong refs to my deployment.  They all have to be 
cleared or you face a OOM: PermGen after a few redeployments.  In this case 
I'd use a stop() + finalize() on my service which clears them.

2a) OK, you say, just stash an Object or something that isn't from my 
deployment's classloader.  Nevertheless, every time you redeploy, you're 
now permanently leaking data and you *will* run out of heap space 
eventually, even if your deployment is meticulous about cleaning up references.

My solution solves the problem by having a "key" (similar to your 
Reference<?> above) - however the difference is that you use one key 
instead of many References (for a space savings), so it works like this:

- App keeps strong reference to key
- Class(loader) keeps a weak->strong map of keys to refs
- When app is removed, the key goes away, and all the references simply 
clean themselves up (in other words, no special action is needed on the 
part of the app to clean up refs stashed on other class(loader)s)

Using a CAS linked list like you describe would be very nice, from a 
performance perspective, but you lose a little of the manageability that 
you would gain from not having to worry about manually cleaning up all your 
junk.

- DML



More information about the core-libs-dev mailing list