有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java独立jdbcpool实现内存泄漏

我正试图在一个独立的web应用程序中实现jdbc池(自包含——不依赖server.xml),这样就可以将其移动到tomcat安装中,可能早于7.0

我使用sourceforge驱动程序(net.sourceforge.jtds.jdbc.driver)连接到MSSQL服务器

除此错误外,一切正常:

SEVERE: The web application [/jdbc-pool] appears to have started a thread named [[Pool-Cleaner]:Tomcat Connection Pool[1-12524859]] but has failed to stop it. This is very likely to create a memory leak.

基于this,我决定需要关闭jdbc池数据源。不过,我对那篇帖子的最后一句话感到不安:

>> If it is configured in the application context, then this simply means you forgot to call DataSource.close on the connection pool when your web application is stopped.

> This is confusing advice because javax.sql.DataSource doesn't have a close() method.

In order to call close, one has to cast it to what ever the data source you are using.

如何找出我正在使用的数据源类型以及它的类在哪里?我能从驱动程序罐中提取出来吗

除了使用池的servlet之外,我还使用了ServletContextListener,这样我就可以立即从contextInitialized方法开始使用池连接。我开始在这个ServletContextListener的contextDestroyed方法中添加代码来终止连接,但在问号处挂断了:

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.sql.DataSource;

public class JdbcPoolListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent myServletContextEvent) {

        // initialize jdbc-pool datasource to start out with pooled connections 
        try {
            Context myContext = (Context) new InitialContext().lookup("java:comp/env");
            DataSource myDataSource = (DataSource) myContext.lookup("jdbc/db");
            myServletContextEvent.getServletContext().setAttribute("JdbcPool", myDataSource);
        } catch (NamingException e) {
            System.out.println("Error initializing jdbc-pool datasource");
            e.printStackTrace();
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent myServletContextEvent) {

        // failed attempt to close the data source
        ServletContext myServletContext = myServletContextEvent.getServletContext();
        //DataSource myDataSource = (DataSource) myServletContext.getAttribute("JdbcPool");
        DataSource dataSource = (DataSource)((???) myServletContext.getAttribute(contextAttribute)).getConfiguration().getEnvironment().getDataSource();
        dataSource.close();
        myServletContext.removeAttribute("JdbcPool");

        // deregister JDBC driver to prevent Tomcat 7 from complaining about memory leaks
        Enumeration<Driver> drivers = DriverManager.getDrivers();
        while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
                System.out.println(String.format("Deregistering jdbc driver: %s", driver));
            } catch (SQLException e) {
                System.out.println(String.format("Error deregistering driver %s", driver));
                e.printStackTrace();
            }
        }
    }
}

共 (0) 个答案