[PATCH 0/2] Class- and class loader-local storage (Bug ID #6493635) (original) (raw)
David M. Lloyd david.lloyd at redhat.com
Fri Feb 27 19:44:18 UTC 2009
- Previous message: [PATCH 0/2] Class- and class loader-local storage (Bug ID #6493635)
- Next message: [PATCH 0/2] Class- and class loader-local storage (Bug ID #6493635)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 02/27/2009 01:15 PM, Bob Lee wrote:
On Fri, Feb 27, 2009 at 11:04 AM, David M. Lloyd <david.lloyd at redhat.com> wrote:
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. What's a FooBar? Use cases should be concrete. :-) 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. Can you provide more detail? It sounds to me like you're saying that the service impl classes are in the parent class loader and the server (that binds the services) is in the child class loader, but from my experience, it's usually the other way around.
It comes back to the whole point of the exercise. Using JBoss Marshalling as a concrete use case -
WeakHashMap<Class<?>, Externalizer>()
fails because Externalizer instances are usually customized to the class they externalize (which, by the way, could well be a system class). This means that Externalizer keeps a strong ref to the Class after all.
So we need a map with weak keys -> weak values, and a way to associate a strong ref from the Class. This covers the case of the Class going away. But if the deployment containing the Externalizer goes away? It's a leak, and a big one (it includes the whole classloader of the Externalizer implementation, not to mention the classloader of Externalizer.class itself) unless we can remove the reference somehow. Even if you attempt to work around it by using an intermediate object from the system classloader, like an Object[1], to hold the references, and you manually keep a Set of them and clear them all out on redeploy, you've still leaked an Object[1] on every class or classloader for every redeployment. So it doesn't matter what classloader the service is bound from, though it can exacerbate the problem. If I ever want to associate some data with, say, a class from the system classloader - even if I make that data be a type from the system classloader - that data is now permanent, even when I don't need it anymore. So if I cause a deployment to happen again, which re-executes the association, the old data is now leaked.
Your solution puts permanent, uncollectible data on classloaders, no matter how you slice it. There has to be a way to clean it up.
- DML
- Previous message: [PATCH 0/2] Class- and class loader-local storage (Bug ID #6493635)
- Next message: [PATCH 0/2] Class- and class loader-local storage (Bug ID #6493635)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]