问题
could anyone say what's wrong with my application?
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;
}
This is the only method i call to insert an user in the database, and then if i try to insert another one, launch this exception:
Initial SessionFactory creation failed.java.lang.OutOfMemoryError: PermGen space
UPDATE: I don't know if there's something in hibernate.cfg but here it go:
<?xml version="1.0" encoding="UTF-8"?>
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>
Why this happen and how to fix it ?
Best regards, Valter Henrique.
回答1:
Very common with Hibernate and large project. The PermGen is the place where the classes are stored (this is not the Heap!). Every now class comes into PermGen, and if the project is large enought, the default size of 64MB is not enought anymore.
Hibernate generated Proxy classes for your entities on the fly. This might be a reason why you get this error in the context of Hibernate. The generated classes also might fill the PermGen.
General advice: If it is not a toy project, just increase your PermGen with -XX:MaxPermSize=96M
and you are safe for a while.
Please also note that Web application containers might have problems unloading applications for several reasons (a server wide log4j configuration is a common problem), and all of Hibernates generated classes will be created again and again per webapp. Better restart your server in this case.
回答2:
I have had this problem before and found it was caused by a previous memory leak in the database connection pooling C3PO, which is not shut-down correctly.
The solution, therefore, is to manually hard reset and close the C3PO data sources when the servlet context is undeployed.
So, in a custom ServletContextListener, add the following code in the contextDestroyed(...) method:
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);
}
}
回答3:
The most common root cause of "java.lang.OutOfMemoryError: PermGen space" exceptions is storage leaks triggered by repeatedly hot-loading changes into a web container.
Have you been hot-loading changes into your web container from NetBeans?
Does the problem "go away" if you restart the web container?
If the answer to both questions is "yes" then the chances are that this is your problem.
There are three solutions:
Don't hot-load. Or at least do full restarts of your web container more often.
Increase the limit on the permgen heap using
-XX:MaxPermSize=...
Track down and fix whatever is actually causing the storage leaks.
There is an insidious leak syndrome that occurs with hot-loading. Retaining a reference to one object instance created with the old version of some hot-loaded class will leak all classes loaded by the classes classloader, and all of their statics.
According to @Daniel, Hibernate generates a lot of proxy classes, and that would use permgen space, and could warrant increasing the permgen heap size. I'd expect this to stabilize; i.e. an application that has "warmed up" would not generate any more proxy classes. However, it could be that hot-loading is causing the warmup to happen repeatedly, and the proxy classes are leaking as above.
回答4:
You could increase permanent generation size , you should add -XX:MaxPermSize=128m
as jvm option. But it is really strange that default perm generation size is not enough for your program..
来源:https://stackoverflow.com/questions/5418318/hibernate-outofmemoryerror-permgen-space