I probably should have also mentioned that the new Thread() leak has
been fixed for Java 1.5, although I'd expect you'd still need to deal
with clearing sharedConfiguration somehow.
On 10/18/07, Andrus Adamchik <andru..bjectstyle.org> wrote:
> Hi Mike,
>
> Good stuff - we need to clean it up. I was not aware of the issue
> with Configuration shutdown hook. Looking at the code, there is no
> excuse for creating it eagerly for every instance. Let me actually
> fix it now.
>
> Regarding EventManager, this is a known issue. There is an
> EventManager.shutdown() method added in 3.0 (CAY-610) and we are
> planning to weed out a few remaining references to the default static
> EM (CAY-868) that leaks just a few threads.
>
> Andrus
>
>
> On Oct 18, 2007, at 10:41 PM, Mike Kienenberger wrote:
> > For what it's worth, there's a memory leak in Configuration. I doubt
> > it will affect many people, but it was a significant contributor to
> > the 1.5Gb memory requirements and 35 minutes when running my tests
> > (now down to 400Mb in 25 minutes, although Velocity, StrutsTest, and
> > personal memory leaks contributed some to this issue as well).
> >
> > The problem is that "new Thread()" without "thread.start()" under Java
> > 1.4 leaks memory.
> > Every new instance of Configuration creates a new Thread() without
> > starting it, and since this is an inner class for Configuration,
> > configuration leaks. And that pretty much leaks the entire Cayenne
> > runtime.
> >
> > All of my Cayenne tests create a new configuration, so this was a
> > problem for me.
> >
> > Here's how I solved it in case anyone else has the same situation. I
> > subclassed DefaultConfiguration (which is the superclass for all of my
> > other classes) as follows, and then called the "clear()" method in my
> > teardown().
> >
> >
> > public class CleanableDefaultConfiguration extends
> > DefaultConfiguration
> > {
> > public CleanableDefaultConfiguration()
> > {
> > super();
> > }
> >
> > public CleanableDefaultConfiguration(String
> > domainConfigurationName)
> > {
> > super(domainConfigurationName);
> > }
> >
> > public void clear() {
> > uninstallConfigurationShutdownHook();
> > ((Thread)configurationShutdownHook).start();
> > try {
> > ((Thread)configurationShutdownHook).join();
> > } catch (InterruptedException e) {
> > Thread.currentThread().interrupt();
> > e.printStackTrace();
> > }
> > configurationShutdownHook = null;
> > shutdown();
> > this.setResourceLocator(null);
> > sharedConfiguration = null;
> > }
> > }
> >
> >
> > I also found issues with EventManager. There's no public interface
> > to reset it. Here's what I ended up doing, but at some point there
> > probably should be a way made to handle this with standard java code,
> > and also shut down the EventManager.Dispatch threads. Currently
> > those threads run until the JVM dies, and since they are inner classes
> > to EventManager, that means EventManager and its referents can't be
> > garbage collected.
> >
> > What I did was used reflection to clear out the subjects and
> > eventQueue fields, which cuts down on the impact of the leak.
> >
> > // defaultManager is final -- can't reset it in java 1.4.
> > EventManager defaultManager = EventManager.getDefaultManager
> > ();
> > Field eventManagersubjectsField =
> > EventManager.class.getDeclaredField("subjects");
> > eventManagersubjectsField.setAccessible(true);
> > eventManagersubjectsField.set(defaultManager,
> > Collections.synchronizedMap(new WeakHashMap()));
> > Field eventManagereventQueueField =
> > EventManager.class.getDeclaredField("eventQueue");
> > eventManagereventQueueField.setAccessible(true);
> > eventManagereventQueueField.set(defaultManager,
> > Collections.synchronizedList(new LinkedList()));
> >
> >
> > Again, probably not an issue for most use cases, but with 800+
> > integration tests, it's an issue for me.
> >
>
>
This archive was generated by hypermail 2.0.0 : Thu Oct 18 2007 - 16:03:37 EDT