On 21/12/2009 14:11, Rainer Frey (Inxmail GmbH) wrote:
> On Monday 21 December 2009 12:04:59 Mark Thomas wrote:
>> My guess is that you are relying on the auto-driver registration
>> process. It is this process that triggers the memory leak so Tomcat now
>> forcibly de-registers any drivers the JVM auto-registers.
> 
> I do, mostly on the presence of a static initializer block in the driver 
> class, as most drivers that we use do not yet implement JDBC4 fully.
> What exactly is the memory leak? Is relying on the auto-registration 
> discouraged altogether, or is the service definition method of JDBC 4 safe?

The memory leak is caused by the DriverManager implementation. It holds
a reference to the Driver. If the Driver was loaded by the web
application then the Driver holds a reference to the WebappClassLoader.
This in turn holds references to every class it has ever loaded. This
can result in a significant PermGen leak on application reload.

All the methods I have looked at do auto-registration but never
de-registration. Given how DriverManager works that is a guaranteed
memory leak on reload. In certain circumstances you can rely on
auto-registration but it is safe to register and deregister yourself.

>> If you get a chance before I get to it later today, try using a context
>> listener to register and de-register the driver when your app starts and
>> stops and let us know how you get on.
> 
> I implemented the ServletContextListener below, and I don't get any 
> exceptions 
> anymore.

That is exactly the sort of thing I had in mind.

> But I'm not sure about this thing. Are drivers required by spec to 
> provide a public parameterless constructor, and is it safe to create and 
> manage instances of a Driver on my own?

Most do, but it doesn't appear to be required. In your circumstances,
you could use a LifecycleListener defined at the container level that
just called Class.forName(String). In that scenario the common class
loader would load the driver (as now) but it would also be the context
class loader so DriverManager would pin the common class loader in
memory which is not an issue (since it is never reloaded). In this case
the memory leak protection code wouldn't kick in on webapp reload and
all would be fine in your app.

> Or do I need a separate instantiation 
> mechanism for each supported driver? I always regarded  these things as 
> internal to the driver implementation. Maybe you were thinking of a different 
> approach to deregister and register a driver that I just don't see?

I am afraid not. DriverManager and container environments can play
together nicely but you do need to be very careful. Unfortunately, this
is an issue that web app developers are not that familiar with.

Mark



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

Reply via email to