This discussion is archived
4 Replies Latest reply: Apr 12, 2007 10:25 AM by 524806 RSS

Environment(s) still being referenced by CurrentTransaction?

524806 Newbie
Currently Being Moderated
Recently (I think), the Environments we seek to close and dereference at the completion of a job have been sticking around. Using jhat, the culprit reference seems to be via a CurrentTransaction instance in the CurrentTransaction class static envMap.

I think the WeakHashMap there is used in a way that won't have the desired effect. Namely, only the keys of this map are held weakly -- the values are held normally. The value is a CurrentTransaction instance, which itself has a strong reference back to the (Environment) key... so there's no way the weak reference will be cleared.

This would also explain why jhat is showing ref chains through this structure from rootset even when choosing 'exclude weak refs'.

Looking back, the code looks the same at least as far back as 2.1.30 (the source I happen to have around) -- but I think we would have noticed this earlier, so maybe we've just now started doing something that triggers this. Still investigating on this side -- but is CurrentTransaction's envMap working as it should?

- Gordon @ IA
  • 1. Re: Environment(s) still being referenced by CurrentTransaction?
    greybird Expert
    Currently Being Moderated
    Hi Gordon,

    You're right, we're doing exactly what is warned against in the javadoc for WeakHashMap. I'll correct this and post a patch for this problem here. If you'd like me to send you a JE 3.2.23+ jar file with the fix, please send me email. I apologize, this is my bug.

    Mark
  • 2. Re: Environment(s) still being referenced by CurrentTransaction?
    greybird Expert
    Currently Being Moderated
    Gordon,

    I added a test case that checks that the finalize() method of the Environment is called when it is closed and GC occurs, after being referenced by CurrentTransaction. Strangely enough, finalize() is called, without any code changes. I'll have to investigate further.

    Mark
  • 3. Re: Environment(s) still being referenced by CurrentTransaction?
    greybird Expert
    Currently Being Moderated
    Gordon,

    My previous test was incorrect. I've reproduced the problem and verified the fix below.

    Thanks very much for isolating this!

    If anyone would like a JE jar file with this fix, please email me at my oracle address: mark.hayes

    This bug causes a memory leak for applications where both of the following are true:
    - Many Environment objects are opened and closed.
    - The CurrentTransaction or TransactionRunner class is used.

    Mark
    --------
    *** src/com/sleepycat/collections/CurrentTransaction.java     1 Feb 2007 14:49:39 -0000     1.46.2.1
    --- src/com/sleepycat/collections/CurrentTransaction.java     12 Apr 2007 16:02:18 -0000
    ***************
    *** 8,13 ****
    --- 8,14 ----
     
      package com.sleepycat.collections;
     
    + import java.lang.ref.WeakReference;
      import java.util.ArrayList;
      import java.util.List;
      import java.util.WeakHashMap;
    ***************
    *** 71,80 ****
           */
          static CurrentTransaction getInstanceInternal(Environment env) {
              synchronized (envMap) {
    !             CurrentTransaction myEnv = (CurrentTransaction) envMap.get(env);
                  if (myEnv == null) {
                      myEnv = new CurrentTransaction(env);
    !                 envMap.put(env, myEnv);
                  }
                  return myEnv;
              }
    --- 72,85 ----
           */
          static CurrentTransaction getInstanceInternal(Environment env) {
              synchronized (envMap) {
    !             CurrentTransaction myEnv = null;
    !             WeakReference myEnvRef = (WeakReference) envMap.get(env);
    !             if (myEnvRef != null) {
    !                 myEnv = (CurrentTransaction) myEnvRef.get();
    !             }
                  if (myEnv == null) {
                      myEnv = new CurrentTransaction(env);
    !                 envMap.put(env, new WeakReference(myEnv));
                  }
                  return myEnv;
              }
  • 4. Re: Environment(s) still being referenced by CurrentTransaction?
    524806 Newbie
    Currently Being Moderated
    Thanks, Mark!

    I think we'll use the patch to include a single overlay class, so that we can continue bundling the standard JAR.

    - Gordon @ IA