Java 如何避免Tomcat application.war文件上的DB2驱动程序类加载器内存泄漏

Java 如何避免Tomcat application.war文件上的DB2驱动程序类加载器内存泄漏,java,tomcat,db2,jndi,connection-pooling,Java,Tomcat,Db2,Jndi,Connection Pooling,IBM支持良好的JDBC驱动程序与Tomcat支持良好的连接池相结合,造成内存泄漏。 请参阅 我不理解建议的解决方案,因为它与最推荐的将驱动程序jar包含在Tomcat lib目录中的做法相冲突 我们需要共享部署和重新部署,而不需要Tomcat重新启动。如果您有此软件组合和所述问题的经验,请在此分享您的解决方案。这是IBM JDBC驱动程序版本4.19(无法禁用的计时器任务)中确认的错误。解决方法是降级到版本4.18。对于驱动程序版本4.22.29,我目前正在ServletContextList

IBM支持良好的JDBC驱动程序与Tomcat支持良好的连接池相结合,造成内存泄漏。 请参阅

我不理解建议的解决方案,因为它与最推荐的将驱动程序jar包含在Tomcat lib目录中的做法相冲突


我们需要共享部署和重新部署,而不需要Tomcat重新启动。如果您有此软件组合和所述问题的经验,请在此分享您的解决方案。

这是IBM JDBC驱动程序版本4.19(无法禁用的计时器任务)中确认的错误。解决方法是降级到版本4.18。

对于驱动程序版本4.22.29,我目前正在ServletContextListener中使用以下代码:

@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
    // This fixes the JDBC driver not unloading corectly on a context reload  for DB2 JDBC 4.22.29
    try {
        logger.debug("Trying to stop the timer");
        new com.ibm.db2.jcc.am.iq() {
            // instance initializer to execute the fix when the anonymous class is instantiated, i.e. now
            {
                if (a != null) {
                    a.cancel();
                } else {
                    logger.debug("Timer is null, skipped");
                }
            }
        };
        logger.debug("Stopped the timer");
    } catch (Exception e) {
        logger.error("Could not stop the DB2 timer thread", e);
    }
}
注意:由于DB2驱动程序JAR看起来很模糊,计时器存储(
com.ibm.DB2.jcc.am.iq.a
)对于其他驱动程序版本可能会有所不同。另外,您正在子类化的类的构造函数可能有副作用,在我的例子中没有副作用

我是如何得到这个解决方案的 获得异常

java.lang.NullPointerException
    at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1600)
    at com.ibm.db2.jcc.am.wd.run(wd.java:49)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.ibm.db2.jcc.am.GlobalProperties.a(GlobalProperties.java:146)
    at com.ibm.db2.jcc.am.GlobalProperties.d(GlobalProperties.java:100)
    at com.ibm.db2.jcc.am.dr.run(dr.java:124)  <------- point of interest <----------
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
java.lang.NullPointerException
位于org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1600)
com.ibm.db2.jcc.am.wd.run(wd.java:49)
位于java.security.AccessController.doPrivileged(本机方法)
com.ibm.db2.jcc.am.GlobalProperties.a(GlobalProperties.java:146)
位于com.ibm.db2.jcc.am.GlobalProperties.d(GlobalProperties.java:100)

在com.ibm.db2.jcc.am.dr.run(dr.java:124)4.19.66版的修复程序:

public void contextDestroyed(ServletContextEvent servletContextEvent) {
    // This fixes the JDBC driver not unloading corectly on a context reload  for DB2 JDBC 4.19.66
    try {
        System.out.println("Trying to stop the DB2 timer thread");
        new com.ibm.db2.jcc.am.tp() {
            {
                if (a != null) {
                    a.cancel();
                } else {
                    System.out.println("Timer is null, skipped");
                }
            }
        };
        System.out.println("Stopped the timer");
    } catch (Exception e) {
        System.out.println("Could not stop the DB2 timer thread " + e.getMessage());
    }
}

Tomcat和DB2JDBC驱动程序版本4.22.29也遇到同样的问题。您在哪里发现这是版本4.19的确认错误?这对DB2V11驱动程序V4.24.92是否仍然有效?可能不是。我按照Phant0MPOST中的流程,将代码改编为我正在使用的db2版本。您必须对您的版本执行相同的操作。
public void contextDestroyed(ServletContextEvent servletContextEvent) {
    // This fixes the JDBC driver not unloading corectly on a context reload  for DB2 JDBC 4.19.66
    try {
        System.out.println("Trying to stop the DB2 timer thread");
        new com.ibm.db2.jcc.am.tp() {
            {
                if (a != null) {
                    a.cancel();
                } else {
                    System.out.println("Timer is null, skipped");
                }
            }
        };
        System.out.println("Stopped the timer");
    } catch (Exception e) {
        System.out.println("Could not stop the DB2 timer thread " + e.getMessage());
    }
}