On 24/09/2014 10:49, Konstantin Kolinko wrote:
> 2014-09-23 17:53 GMT+04:00 Phil Steitz <phil.ste...@gmail.com>:
>> On 9/23/14 6:04 AM, ma...@apache.org wrote:
>>> Author: markt
>>> Date: Tue Sep 23 13:04:52 2014
>>> New Revision: 1626998
>>>
>>> URL: http://svn.apache.org/r1626998
>>> Log:
>>> Prevent potential memory leaks when the Pool is dereferenced without being 
>>> closed.
>>>
>>> Modified:
>>>     commons/proper/pool/trunk/src/changes/changes.xml
>>>     
>>> commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
> 
> (...)
> 
>>> Modified: 
>>> commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
>>> URL: 
>>> http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java?rev=1626998&r1=1626997&r2=1626998&view=diff
>>> ==============================================================================
>>> --- 
>>> commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
>>>  (original)
>>> +++ 
>>> commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
>>>  Tue Sep 23 13:04:52 2014
>>> @@ -20,6 +20,7 @@ import java.io.PrintWriter;
>>>  import java.io.StringWriter;
>>>  import java.io.Writer;
>>>  import java.lang.management.ManagementFactory;
>>> +import java.lang.ref.WeakReference;
>>>  import java.util.Iterator;
>>>  import java.util.TimerTask;
>>>  import java.util.concurrent.atomic.AtomicLong;
>>> @@ -94,9 +95,10 @@ public abstract class BaseGenericObjectP
>>>      /*
>>>       * Class loader for evictor thread to use since in a J2EE or similar
>>>       * environment the context class loader for the evictor thread may have
>>> -     * visibility of the correct factory. See POOL-161.
>>> +     * visibility of the correct factory. See POOL-161. Uses a weak 
>>> reference to
>>> +     * avoid potential memory leaks if the Pool is discarded rather than 
>>> closed.
>>>       */
>>> -    private final ClassLoader factoryClassLoader;
>>> +    private final WeakReference<ClassLoader> factoryClassLoader;
>>>
>>>
>>>      // Monitoring (primarily JMX) attributes
>>> @@ -137,7 +139,8 @@ public abstract class BaseGenericObjectP
>>>          this.creationStackTrace = getStackTrace(new Exception());
>>>
>>>          // save the current CCL to be used later by the evictor Thread
>>> -        factoryClassLoader = 
>>> Thread.currentThread().getContextClassLoader();
>>> +        factoryClassLoader = new WeakReference<ClassLoader>(
>>> +                Thread.currentThread().getContextClassLoader());
> 
> I think that Thread.currentThread().getContextClassLoader() may return
> null if the pool is used in a standalone application. This will break
> the "if (cl == null)" check added to Evictor.run() method below.

I did some quick checking. The only way I can get that to return null is
if I use:

Thread.currentThread().setContextClassLoader(null);

I can't think of a valid reason for doing that but I have got a patch
that will protect against this so, give the wide range of code Pool gets
used in, I'll add that protection.

Mark


> 
>>>          fairness = config.getFairness();
>>>      }
>>>
>>> @@ -251,7 +254,7 @@ public abstract class BaseGenericObjectP
>>>      public final boolean getLifo() {
>>>          return lifo;
>>>      }
>>> -
>>> +
>>>      /**
>>>       * Returns whether or not the pool serves threads waiting to borrow 
>>> objects fairly.
>>>       * True means that waiting threads are served as if waiting in a FIFO 
>>> queue.
>>> @@ -997,8 +1000,14 @@ public abstract class BaseGenericObjectP
>>>                      Thread.currentThread().getContextClassLoader();
>>>              try {
>>>                  // Set the class loader for the factory
>>> -                Thread.currentThread().setContextClassLoader(
>>> -                        factoryClassLoader);
>>> +                ClassLoader cl = factoryClassLoader.get();
>>> +                if (cl == null) {
>>> +                    // The pool has been dereferenced and the class loader 
>>> GC'd.
>>> +                    // Cancel this timer so the pool can be GC'd as well.
>>> +                    cancel();
>>> +                    return;
>>> +                }
>>> +                Thread.currentThread().setContextClassLoader(cl);
>>>
>>>                  // Evict from the pool
>>>                  try {
>>>
>>>
>>>
> 
> 
> Best regards,
> Konstantin Kolinko
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
> For additional commands, e-mail: dev-h...@commons.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to