Re: Memory leak of Configuration under Java 1.4, also EventManager

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Thu Oct 18 2007 - 15:51:36 EDT

  • Next message: Mike Kienenberger: "Re: Memory leak of Configuration under Java 1.4, also EventManager"

    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 - 15:52:10 EDT