Hibernate java.lang.OutOfMemoryError:Java堆空间

我有一个在Tomcat 7上运行的Java Web应用程序 – jdk1.7

此应用程序使用Spring 4.1.5.RELEASE和Hibernate 4.2.2.Final

我的问题是建筑部分工厂的堆空间的OutOfMemoryException

这是我打开SessionFactory的静态方法

public class GenericDAO { public static SessionFactory sessionFactory = null; public static ServiceRegistry serviceRegistry = null; Transaction tx = null; public static SessionFactory createSessionFactory() { Configuration configuration = new Configuration(); configuration.configure(); serviceRegistry = new ServiceRegistryBuilder().applySettings( configuration.getProperties()). buildServiceRegistry(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); return sessionFactory; } } 

这是DAO的一个例子

 public class SpecificDAO extends GenericDAO { public int save(MyObject item) { Session session = createSessionFactory().openSession(); try { tx = session.beginTransaction(); session.save(item); tx.commit(); return item.getId(); } catch (HibernateException e) { if (tx != null) tx.rollback(); e.printStackTrace(); } finally { session.close(); } return -1; } } 

错误发生在包含的行

sessionFactory = configuration.buildSessionFactory(serviceRegistry);

问题不会在部署时立即发生,而是在使用2到3天后发生

这是我的Hibernate.cfg.xml

    jdbc:sqlserver://192.168.XX.XXX:1433;databaseName=DatabaseName com.microsoft.sqlserver.jdbc.SQLServerDriver username password   <!-- update -->   

您必须只创建一次会话工厂,因为它是一个重量级的对象,请参阅hibernate文档了解其详细信息。

以下是doc应如何创建的示例代码:

 import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration().configure().buildSessionFactory( new StandardServiceRegistryBuilder().build() ); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } } 

最好在使用后刷新和清除会话,您可以同时使用它们

 session.flush(); session.clear(); 

有关link1和link2的更多信息

您正在为每个save()调用创建一个SessionFactory对象。

即您为每个save()调用重复创建一个新的SessionFactory但不关闭内存中的现有SessionFactory对象。

调用save()多少次? 同样没有SessionFactory将在内存中,这会导致内存泄漏。

SessionFactory是重量级对象,因此您可以在应用程序初始化时创建。 您可以创建SingleTon来实例化SessionFactory。

避免在每个DAO操作上实例化SessionFactory对象。 它非常慢并导致内存泄漏。 在这个答案中更好地解释

如果您仍在使用Spring ,最好委托Spring使用SessionFactory,事务和处理SQLexception。 例如,save()方法将减少到一行代码sessionFactory.getCurrentSession().save(item); 手动事务打开/提交/回滚应替换为@Transactional属性。 此外,通常更好地将事务放在整个服务方法上,而不是放在每个DAO方法上,但它取决于业务逻辑。

这里的示例如何配置Spring上下文以使用Hibernate (只是谷歌的第一篇文章)

我稍微采用了这个例子来解决当前的问题

 @Repository public class SpecificDAO { private SessionFactory sessionFactory; @Autowired public SpecificDAO(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Transactional(propagation=Propagation.REQUIRED) public int save(MyObject item) { try{ sessionFactory.getCurrentSession().save(item); }catch (HibernateException e) { return -1; } } } 

弹簧配置

             it.company.client.project.hibernate.MyObject     org.hibernate.dialect.SQLServerDialect org.hibernate.connection.DatasourceConnectionProvider false