Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
None
-
Operating System: Windows XP
Platform: PC
-
37926
Description
Using:
commons-dbcp-1.2.1
commons-pool-1.2
When using BasicDataSource, if the datasource is initialized while the database
is down, or a wrong user/pass is given, each call to getConnection() results in
a memory leak.
Here's what I've tracked down:
In the BasicDataSource.createDataSource method, if the datasource was
previously un-initialized, a new GenericObjectPool (or AbandonedObjectPool
depending on configuration) is always instantiated.
The GenericObjectPool constructor (and also the call to
setTimeBetweenEvictionRunsMillis()) starts a new thread for the Evictor. This
thread runs until it's cancel() is called.
The problem is that if a SQLException is thrown when the
PoolableConnectionFactory is instantiated (like with a bad user/pass), the
exception is rethrown, but no attempt is made to clean up the Evictor thread
that was started in the GenericObjectPool, so that thread just keeps running
forever. Since this happens before the datasource was created, the next call
to getConnection() will again attempt to re-initialize the datasource in
createDataSource(), and if the same error happens again, another Evictor thread
will be left running, -> repeat a few thousand times and it starts to bring
down systems.
Changing BasicDataSource to only initialize the connectionPool when it is null
seemed resolve the issue. Alternatively, catching the exception, and calling
close() on the pool (which then cancel()'s the Evictor) also seemed to work.
Environment:
WinXP
SQL2000
JSQLConnect driver