Hibernate:OutOfMemoryError:PermGen空间

Val*_*lva 3 java hibernate exception out-of-memory

有谁可以说我的申请有什么问题?

public class HibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

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

public boolean insertUser(User user) {
    Session session = HibernateUtil.getSessionFactory().openSession();
    try {
        session.beginTransaction();
        session.save(user);
        session.getTransaction().commit();

    } catch (HibernateException he) {
        session.getTransaction().rollback();
        return false;
    }finally{
        if (session != null){
            session.close();
        }
    }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

这是我调用在数据库中插入用户的唯一方法,然后如果我尝试插入另一个,则启动此异常:

Initial SessionFactory creation failed.java.lang.OutOfMemoryError: PermGen space
Run Code Online (Sandbox Code Playgroud)

更新:我不知道hibernate.cfg中是否有什么东西,但是它在这里:

<?xml version="1.0" encoding="UTF-8"?>
Run Code Online (Sandbox Code Playgroud)

org.hibernate.dialect.MySQLDialect com.mysql.jdbc.Driver jdbc:mysql:// localhost:3306/XXXXX XXXX XXXXc thread

    <!-- Connection pool C3P0 -->
    <property name="hibernate.c3p0.acquire_increment">2</property>
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">100</property>
    <property name="hibernate.c3p0.timeout">20</property>
    <property name="hibernate.c3p0.max_statements">50</property>
    <property name="hibernate.c3p0.idle_test_period">60</property>

    <!-- To show sql output on the screen -->
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>

    <!-- Mapping the tables in my schema -->
    ...

</session-factory>
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况以及如何解决?

此致,Valter Henrique.

Dan*_*iel 7

Hibernate和大型项目很常见.PermGen是存储类的地方(这不是堆!).现在每个类都进入PermGen,如果项目很大,则不再需要64MB的默认大小.

Hibernate动态为您的实体生成代理类.这可能是您在Hibernate环境中出现此错误的原因.生成的类也可能填充PermGen.

一般建议:如果它不是玩具项目,只需增加你的PermGen,-XX:MaxPermSize=96M你就会安全一段时间.

还请注意,Web应用程序容器可能由于多种原因而无法卸载应用程序(服务器范围的log4j配置是常见问题),并且将根据webapp一次又一次地创建所有Hibernates生成的类.在这种情况下,最好重启服务器.


小智 5

我以前遇到过这个问题,发现它是由数据库连接池C3PO中的先前内存泄漏引起的,该连接没有正确关闭.

因此,解决方案是在取消部署servlet上下文时手动硬重置和关闭C3PO数据源.

因此,在自定义ServletContextListener中,在contextDestroyed(...)方法中添加以下代码:

Set<PooledDataSource> pooledDataSourceSet = (Set<PooledDataSource>) C3P0Registry.getPooledDataSources();

    for (PooledDataSource dataSource : pooledDataSourceSet) {
        try {
            dataSource.hardReset();
            dataSource.close();
        } catch (SQLException e) {
            // note - do not use log4j since it may have been unloaded by this point
            System.out.println("Unable to hard reset and close data source.", e);
        }
    }
Run Code Online (Sandbox Code Playgroud)