I have been receiving PERM GEN errors.
After reading Frank Kievet's blog about memory leaks, I started investigating.
http://frankkieviet.blogspot.com/2006/10/classloader-leaks-dreaded-permgen-space.html
http://frankkieviet.blogspot.com/2006/10/how-to-fix-dreaded-permgen-space.html
I added his code for causing a garbage collection in the perm gen and noticed that a lot of memory was being lost on each redeploy of the web app.
I downloaded the Eclipse, stand-alone Memory Analyzer (MAT).
http://www.eclipse.org/mat/
My steps to find the leak:
- I ran the web app and used MAT to obtain a heap dump from Tomcat.
- I reran the web app again and obtained another heap dump.
- I opened the dominator tree for each dump.
- The second dump contained the web app loader from the first dump. This class is causing the class loader memory leak.
- In the second dominator tree, I right-clicked the stale web app loader and selected Path to GC Roots (excluding weak references).
- The references listed are the ones causing the memory leak.
https://hibernate.atlassian.net/browse/HHH-7364
http://stackoverflow.com/questions/11872316/tomcat-guice-jdbc-memory-leak
http://docs.oracle.com/cd/E17952_01/connector-j-relnotes-en/news-5-1-23.html
I also had to update several jar files to newer versions:
hibernate-c3p0-4.1.1.Final.jar
mysql-connecto-java-5.1.28-bin.jar
package shared;
import com.mysql.jdbc.AbandonedConnectionCleanupThread;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.Enumeration;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class WebappListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
try {
AbandonedConnectionCleanupThread.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Enumeration
while (enumer.hasMoreElements()) {
DriverManager.deregisterDriver(enumer.nextElement());
}
} catch (java.sql.SQLException se) {
se.printStackTrace();
}
shared.HibernateHelper.closeFactory();
}
}
The HibernateHelper class is a helper class for using Hibernate. All the methods are static. It has a static variable for the session factory that already exists.
static public void closeSessionFactory(SessionFactory factory) {
if (factory != null) {
if (factory instanceof SessionFactoryImpl) {
SessionFactoryImpl sf = (SessionFactoryImpl) factory;
ConnectionProvider conn = sf.getConnectionProvider();
if (conn instanceof C3P0ConnectionProvider) {
((C3P0ConnectionProvider) conn).close();
}
}
factory.close();
}
}
static public void closeFactory() {
closeSessionFactory(sessionFactory);
}
The relevant imports for this method are:
import org.hibernate.SessionFactory;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
No comments:
Post a Comment