Hibernate:OutOfMemoryError:PermGen空间

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

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; } 

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

 Initial SessionFactory creation failed.java.lang.OutOfMemoryError: PermGen space 

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

  

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

   2 5 100 20 50 60  true true  ...  

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

此致,Valter Henrique。

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

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

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

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

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

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

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

 Set pooledDataSourceSet = (Set) 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); } } 

“java.lang.OutOfMemoryError:PermGen space”exception的最常见根本原因是由于反复将热更改加载到Web容器中而触发的存储泄漏。

  • 您是否已从NetBeans将更改加载到Web容器中?

  • 如果重新启动Web容器,问题是否“消失”?

如果两个问题的答案都是“是”,则可能是这是您的问题。

有三种解决方案:

  • 不要热负荷。 或者至少更频繁地重新启动Web容器。

  • 使用-XX:MaxPermSize=...增加permgen堆的限制-XX:MaxPermSize=...

  • 追踪并修复实际导致存储泄漏的任何问题。

热负荷会发生阴险的泄漏综合症。 保留对使用旧版本的某个热载类创建的一个对象实例的引用将泄漏类类加载器加载的所有类及其所有静态。


根据@Daniel的说法,Hibernate生成了很多代理类,并且会使用permgen空间,并且可以保证增加permgen堆大小。 我希望这会稳定下来; 即,已经“预热”的应用程序不会再生成任何代理类。 然而,可能是热负载导致热重复发生,并且代理类如上所述泄漏。

您可以增加永久生成大小,您应该添加-XX:MaxPermSize=128m作为jvm选项。 但是对于你的程序来说,默认的perm生成大小是不够的,这真的很奇怪。