2009/2/7 Gili <[email protected]> > Hi, > > I noticed you guys committed some new code to tackle the memory leaks > recently so I gave it a spin. I still see the memory leak under > Glassfish v2ur2 and the GC root that is keeping the instances alive > seems to be com.google.inject.internal.Finalizer. > > Stuart, can you please look into whether Glassfish or Guice is at > fault here? >
Hi Gili, The current reference cache in Guice relies on a background worker thread to dequeue and finalize references. Because an active Java thread is a GC root this thread must be stopped when it's no longer required, otherwise any classes that it refers to (and their classloaders) cannot be collected. There are various ways to do this - some libraries expose a public API that containers can use to tell the thread when to stop. Others use "declarative" metadata (such as the Bundle-Activator manifest entry in OSGi) to refer to names of helper classes that can take part in certain managed lifecycles. The approach used in Guice (and google-collections) is for the thread itself to try and detect when it's no longer required. It does this by waiting to see when the reference queue's classloader is eligible for GC, which means the client application no longer (strongly) refers to the queue. For this to work properly the worker thread must have no strong references to the client application's classloader, otherwise it would indirectly keep the queue alive. This is why Bob's code goes to great lengths to try and load the worker class in a separate classloader unconnected to the application. While this works in most environments, there are two potential references that can occur when you spawn a thread from a container managed thread: 1) the new thread automatically picks up any InheritedThreadLocals 2) it gets the current AccessControlContext (only when security is on) These references are internal to the thread and cannot be removed using the public API or other runtime independent methods. So if either of these situations occur the worker thread will not stop and you will see a "leak". 1) could occur for many reasons, such as an application or container not removing its thread locals before returning a thread to the common pool. 2) is expected in almost all Java EE environments, hence what you see :( So... where do we go from here? Well, you could consider putting Guice on the system or boot classpath, ie. tied to some classloader that's above the client classloader. So while the worker thread will still have a reference to the system-level classloader, it shouldn't stop the client classloader from being unloaded. The downside is that you can't replace Guice without restarting the container - but this might be acceptable, given you're more likely to replace client apps than libraries [ at the very least you'd need the com.google.inject.internal.Finalizer class available on the system / container classpath, you don't need all of Guice ] Another option is to remove the need for a worker thread, but I'm not sure if this is feasible (there are alternative reference maps out there but YMMV :) Note that you'll also have a separate worker thread for each application that jarjars the reference queue under a different package ( ie. if you use Guice and google-collections you might end up with two worker threads! ) Alternatively, the google team could think again about exposing an API to shutdown this thread - or possibly provide a BundleActivator class that could manage the thread from an OSGi perspective, then you wouldn't be exposing a public API but would help anyone using an OSGi container* ;) [ * it would introduce a compile dep on OSGi for the library, but not clients ] The last resort would be to patch Guice to shutdown this thread and use this in your application rather than the official binary - but this may not be an option for everyone ;) Of course once the JDK provides an inbuilt reference map these issues should disappear (and you'd only need one worker thread) - most of the problems stem from doing all of this outside of the JDK core classes! HTH Thanks, > Gili > > -- Cheers, Stuart --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/google-guice?hl=en -~----------~----~----~----~------~----~------~--~---
