On 02/27/2009 12:52 PM, Bob Lee wrote:
On Fri, Feb 27, 2009 at 10:40 AM, David M. Lloyd <david.ll...@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