On 17/05/2013 09:28, Michael-O wrote:
> Hi folks,
> 
> there's now a follow-up on the issue [1].
> Recap: JreMemoryLeakPreventionListener reported that my webapp has spawned 
> OracleTimeoutPollingThread because I have set a QueryTimeout in the JDBC Pool.
> Mark Thomas noted that this is likely a bug in the driver. I have taken 
> action and created a service request with Oracle.
> 
> My personal analysis with VisualVM:
> The thread is spawned when the first query is run. The thread keeps running 
> when the webapp is shut down or undeployed. Classes remain in memory.
> The JDBC Pool does a simple Class.forName to load the driver, it neither uses 
> the DriverManager loading nor does it actively unload the driver.
> 
> Oracle answer:
> They were able to reproduce the issue. The technical analysis says:
> 
>> Hi Michael,
>>
>> I confirmned internally that this message from Tomcat can be ignored as 
>> there is no risk of any real leak from" OracleTimeoutPollingThread" thread.
>> This thread is related to the JDBC driver which may be used by many apps 
>> simultaneously. Unloading the app does not unload the driver and should not 
>> and does not stop the thread.
>>
>> It seems to be the design behaviour.
> 
> So my questions would be:
> 1. Is that still not a false positive?

No, that is not a false positive. The response from Oracle is wrong.

There is nothing wrong with the driver creating the thread or the thread
continuing after the web application has stopped. The problem is as follows:

1. When the JDBC driver creates the Thread, the Thread's context class
loader (as returned by Thread.getContextClassLoader()) is set to the web
application's class loader.

2. The correct behaviour at this point would be for the Driver to set
the Thread's context class loader to the class loader that loaded the
Driver class when the Thread is created.

3. The memory leak occurs as follows:
- the web application is stopped
- Tomcat clears all references to the web application and its classes
- The web application should be eligible for garbage collection
- The JDBC driver is still loaded (as it should be)
- The JDBC driver retains a reference to the Thread (as it should)
- The thread retains a reference to the web application class loader
(this is the memory leak).

The reference chain is:
a) JDBC driver
  b) Thread
    c) Web application class loader
      d) Every class loaded by the web app

Everything from c) onwards should be eligible for garbage collection but
isn't because of the leak in the Thread that is retaining a reference to
the web application class loader.

> 2. Why does the JDBC Pool not unload the driver? That my cause the thread to 
> stop after the last app has been stopped/undeployed.

1. Because the driver is in CATALINA_HOME/lib it is available to other
applications.

2. JDBC drivers are never automatically unloaded. You have to do so
explicitly (not doing so is an other source of memory leaks when the
driver is packaged in WEB-INF/lib).

You need to go back to Oracle.

Mark


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

Reply via email to