Как освободить несколько org.hibernate.impl.SessionFactoryImpl - PullRequest
3 голосов
/ 19 июля 2011

Продолжить решение этой проблемы , я обнаружил несколько утечек памяти в org.hibernate.impl.SessionFactoryImpl, используя MAT :

54 instances of "org.hibernate.impl.SessionFactoryImpl", loaded by "org.apache.catalina.loader.WebappClassLoader @ 0xbb00fb0" occupy 33 962 536 (64,40%) bytes. 

Biggest instances:

org.hibernate.impl.SessionFactoryImpl @ 0x3f026c0 - 652 664 (1,24%) bytes. 
org.hibernate.impl.SessionFactoryImpl @ 0x49018f8 - 652 664 (1,24%) bytes. 
org.hibernate.impl.SessionFactoryImpl @ 0x7b0e2b8 - 652 664 (1,24%) bytes. 
org.hibernate.impl.SessionFactoryImpl @ 0x7d65e60 - 652 664 (1,24%) bytes.
...

Деталь: enter image description here

DaoSF.java

public final class DaoSF implements Serializable
{
  private static final long serialVersionUID = 1L;
  private static SessionFactory sessionFactory;
  private static Session hibSession;

  private synchronized static void initSessionFactory() {
    Configuration config = new Configuration();
    config.configure("hibernate.cfg.xml"); 
    sessionFactory = config.buildSessionFactory();
    hibSession = sessionFactory.getCurrentSession();
  }

  public static SessionFactory getSessionFactory() {
    initSessionFactory();
    return sessionFactory;
  }

  public static Session getSession(){ 
    return hibSession;
  }
}

часть DaoCrud.java:

  public void save(Object dataItem) throws Exception 
  { 
    session = DaoSF.getSessionFactory().openSession();

    Transaction tx = session.beginTransaction();  
    session.save(dataItem);  
    session.flush();
    tx.commit();  

    if (session != null) session.close();
  }

часть Bean.java

 public void save() {
   try {
     mydao.save(item);
   }
   catch (Exception e) {...}
   }  
 }

Что я делаю не так?Как правильно использовать фабрику сессий?Не могли бы вы помочь мне?

Ответы [ 3 ]

7 голосов
/ 19 июля 2011

Будет лучше, если вы создадите Class HibernateSession, который будет обрабатывать транзакции открытия, закрытия и отката.

Вы должны поместить session.close () в оператор finally, а затем присвоить пустое значение сеансу и транзакции, чтобы убедиться, что они будут собирать мусор.

3 голосов
/ 19 июля 2011

Вы создаете и инициализируете новый SessionFactory каждый раз, когда вам нужен сеанс.Ваш метод getSessionFactory должен проверять, есть ли он у вас, вместо того, чтобы всегда создавать новый.

2 голосов
/ 19 июля 2011

Прежде всего вы должны закрыть соединение и сеанс в операторе finally. Может быть, есть некоторые исключения и сессия не закрыта? Во-вторых, в hibernate были ошибки, связанные с отсутствием завершающих сеансов. Посмотрите на эту ветку: OutofMemory: SessionImpl кэшируется даже после закрытия и сброса? .

...