热重新部署和 Oracle 数据库导致永久内存泄漏 [英] Permgen Memory Leak with hot redeploy and Oracle database

查看:70
本文介绍了热重新部署和 Oracle 数据库导致永久内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在生产环境中运行的基于 SpringRoo 的应用程序,在一些热重新部署后导致严重的永久内存泄漏.

i've got a SpringRoo-based application that is running in a production environment, that is causing severe permgen memory leaks after some hot redeploys.

为了查找并修复"泄漏并减少分析过程中的变量,我使用 roo 创建了一个简单、精简的应用程序,并且获得了相同的行为.该项目(使用 Spring Roo (1.2.3.RELEASE) 创建)只是持久化了一个名为Person"的实体和一个名为name"的字符串字段.

In order to "find and fix" the leak and to reduce the variables during analysis, i've created a simple, streamlined application using roo, and i obtain the same behaviour. The project (created with Spring Roo (1.2.3.RELEASE)) simply persists an entity called 'Person' with a string field called 'name'.

我在 Tomcat 7.0.39 上部署 war,使用 Oracle 11.2.0.2 作为数据库.每次重新部署后,我都会在 catalina.out 中收到此消息

I deploy the war on a Tomcat 7.0.39, using Oracle 11.2.0.2 as the database. After every re-deploy, i get this message in catalina.out

INFO: Undeploying context [/ojdbc-0.1.0.BUILD-SNAPSHOT]
mag 06, 2013 10:50:43 AM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/ojdbc-0.1.0.BUILD-SNAPSHOT] registered the JDBC driver       [oracle.jdbc.OracleDriver] but failed to unregister it when the web application was stopped.    To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

在两次热重新部署后,我收到一个 permgen 错误:

After two hot-redeploys, i get a permgen error:

mag 06, 2013 10:51:08 AM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive /Applications/apache-tomcat-7.0.39/webapps/ojdbc-    0.1.0.BUILD-SNAPSHOT.war
Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]"
Exception in thread "RMI TCP Connection(idle)" mag 06, 2013 10:51:17 AM ServerCommunicatorAdmin reqIncoming
WARNING: The server has decided to close this client connection.
java.lang.OutOfMemoryError: PermGen space
Exception in thread "RMI TCP Connection(idle)" java.lang.OutOfMemoryError: PermGen space

我已尝试使用 VisualVm/EclipseMemory Analyzer 对此进行分析,这就是我目前得到的结果.

I've tried to analyze this with VisualVm / EclipseMemory Analyzer, and this is what i get so far.

事实是我没有观察到其他数据库(例如 PostgreSQL 或 Hypersonic)的这种行为.是否存在与 Oracle 相关的问题导致泄漏?

The fact is that i don't observe this behaviour with another database (for example PostgreSQL or Hypersonic). Is there something related to Oracle that is causing the leak?

这里是一个包含 roo 脚本生成器的 zip 存档,anche .hprof转储文件.

Here is a zip archive containing roo script generator, anche the .hprof dump file.

推荐答案

试试这个:

在 web xml 中注册一个 ServletContextListener

Register a ServletContextListener in web xml

<listener>
    <listener-class>my.package.MyShutdownServletContextListener</listener-class>
</listener>

来源:

public class MyShutdownServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
    final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
    try {
        Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
        java.sql.DriverManager.getDrivers();
        Class.forName("oracle.jdbc.driver.OracleTimeoutThreadPerVM");
    } catch (ClassNotFoundException e) {
        /* noop */
    } finally {
        Thread.currentThread().setContextClassLoader(contextClassLoader);
    }
}
@Override
public void contextDestroyed(ServletContextEvent event) {}
}

这篇关于热重新部署和 Oracle 数据库导致永久内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆