Hibernate3.1.3 ClassLoader Memory Leak
i_n_g Sep 6, 2006 1:56 PMThe Hibernate classes and the ClassLoader which loads them are not GCed.
The following example has two classes, "CallJunk" creates a ClassLoader , loads Junk and hibernate classes, and call Junk.main(). Junk.main() opens a session and closes it.
The CallJunk program grows 1-2 MB in each loop step and finally run out of memory.
I profiled with JProfiler, found hibernate classes are duplicated, which is loaded by a new URLClassLoader in the Loop, but never GCed.
package calljunk; import java.io.File; import java.net.URL; import java.net.URLClassLoader; public class CallJunk { static String[] dum=new String[0]; static Class[] parameterTypes = new Class[]{dum.getClass()}; public static void main(String[] args)throws Exception { URL[] urls = new URL[]{ new File("../junk/cglib-2.1.3.jar").toURL(), new File("../junk/commons-collections-2.1.1.jar").toURL(), new File("../junk/dom4j-1.6.1.jar").toURL(), new File("../junk/ehcache-1.1.jar").toURL(), new File("../junk/hibernate3.jar").toURL(), new File("../junk/jta.jar").toURL(), new File("../junk/postgresql-8.0-311.jdbc3.jar").toURL(), new File("../junk/commons-logging.jar").toURL(), new File("../junk/bin").toURL() }; for (int i=0; i<100; i++) { System.out.println("No "+i+": "); System.in.read(); Class cls = new URLClassLoader(urls).loadClass("junk.Junk"); cls.getMethod("main", parameterTypes).invoke(null, new Object[]{dum}); } } } package junk; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import javax.naming.InitialContext; public class Junk { private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; public static void main(String[] args) throws Exception { Configuration cfg = new Configuration(); SessionFactory sFactory = null; try { cfg.configure(CONFIG_FILE_LOCATION); String sessionFactoryJndiName = cfg.getProperty(Environment.SESSION_FACTORY_NAME); if (sessionFactoryJndiName != null) { cfg.buildSessionFactory(); sFactory = (SessionFactory) (new InitialContext()).lookup(sessionFactoryJndiName); } else { sFactory = cfg.buildSessionFactory(); } } catch (Exception e) { throw new HibernateException("Could not initialize the Hibernate configuration"); } Session s = sFactory.getCurrentSession(); s.close(); sFactory.close(); } }