1 Reply Latest reply on Sep 6, 2006 2:16 PM by i_n_g

    Hibernate3.1.3 ClassLoader Memory Leak

    i_n_g

      The 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();
       }
      
      }