Loading driver jar file at runtime resulting in Perm Gen Space Error

221 views Asked by At

I have created a REST service in which I am loading the JDBC driver jar at runtime. Below is the code which does this:

Driver driverInstance;
URLClassLoader driverClassLoader;
driverClassLoader = new URLClassLoader (new URL[] { "c:/mysql.jar" }, System.class.getClassLoader());
Class<?> driverClass = driverClassLoader.loadClass("oracle.jdbc.driver.OracleDriver");
Connection conn = driverInstance.connect(connectionString, userDbCredentials);

After using this connection to load data into database, I am closing the connection and driverClassLoader both. But after running it for some time, I am getting java.lang.OutOfMemoryError: PermGen space in tomcat server.

I took the heap dump, and open it using eclipse Memory Analyzer and I found that the below Leak suspect message: 13 instances of "org.apache.catalina.loader.WebappClassLoader", loaded by "java.net.URLClassLoader @ 0xc155fc10" occupy 14,083,776 (32.21%) bytes

I understand that it is due to loading of driver jar at runtime but I am unable to find a solution to it.

1

There are 1 answers

0
Mattias Jiderhamn On

When you load the JDBC driver class, it registers itself with java.sql.DriverManager. Even though you try to make the system classloader the parent of your URLClassLoader, I believe it will inherit the AccessControlContext from your WebappClassLoader, thus referencing it. Analyzing the references using Eclipse Memory Analyzer (MAT) could help verify that - see this blog post for instructions.

Assuming that the JDBC driver is in fact the source of the leak, the solution to your problems is to call java.sql.DriverManager.deregisterDriver() to explicitly deregister the driver, preferably in the contextDestroyed() of a ServletContextListener.

Normally you could let my ClassLoader leak prevention library take care of the deregistering for you, however since the driver is loaded in a separate classloader it won't work out of the box. You may however be able to do some subclassing/modification. The benefit would be that you get a lot more leak protection for free.

Whether you really want and need to load drivers from outside the application at runtime - well, that's a separate question...

Good luck!