Java - Tomcat GC不会释放。总是导致崩溃,找不到任何内存泄漏



我的tomcat应用程序几乎没有问题。我使用的是具有1024m内存的Linux服务器。我将应用程序部署在Tomcat上,一切正常。最近,我注意到"终身终身"的堆内存在应该...它达到99%,然后撞车。我使用VisualVM检查了我的应用程序,并且结果相同。它充满了记忆,"旧的gen"永远不会释放。

这是应用程序运行几分钟而没有请求的时候:

img:一切看起来正常

当我开始在循环中发送200个线程的请求时这发生了什么:

img:所有记忆均已完整

所以我检查垫子上的数据,这是我的结果:

img:看起来像记忆泄漏

img:SQL JDBC的问题?

img:无法理解什么是错误的

这是我的ConnectionPool class

public class ConnectionPool {
    private static ConnectionPool singleton = null; 
    private ArrayList<Connection> freeConnections; 
    private ArrayList<Connection> allConnections; 
    private int MAX_CONNECTIONS = 1;
    private final String shema = "Topic";
    private final String url = "jdbc:mysql://localhost:3306/"+shema+"?  autoReconnect=true&useSSL=false";
    private final String username = "root";
    private final String password = "password";


    public static ConnectionPool getInstance(){
        if (singleton == null)
        {
            synchronized (ConnectionPool.class) {
                if (singleton == null){
                    System.out.println("ConnectionPool get instance");
                    try {
                        singleton = new ConnectionPool();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } //this will invoke the constructor
                }
            }
        }
        return singleton;
    }
    private ConnectionPool() throws Exception {
        freeConnections = new ArrayList<Connection>();
        allConnections = new ArrayList<Connection>();
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for (int i = 0; i < MAX_CONNECTIONS; i++) {
            try {
                addNewConnection();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    private void addNewConnection() throws SQLException {
        try {
            Connection conn = DriverManager.getConnection(url, username,  password);
            freeConnections.add(conn);
            allConnections.add(conn);
        } catch (SQLException e) {
            throw e;
        }
    }
    public Connection getConnection() 
    {
        while (true) {
            synchronized (freeConnections) {
                if (freeConnections.size() != 0) { // free connection is  available 
                    Connection conn = freeConnections.get(0);
                    freeConnections.remove(0);
                    try {
                        conn.setAutoCommit(true);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    return conn;
                }
                try {
                    freeConnections.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    public void returnConnection(Connection conn)
    {
        if (null == conn) { // ignore invalid value
            return;
        }
        if (!allConnections.contains(conn)) {
            return;
        }
        synchronized (freeConnections) {
            if (freeConnections.contains(conn)) {
                return;
            }
            freeConnections.add(conn);
            freeConnections.notifyAll();
            return;
        }
    }
    public void closeAllconnections()
    {
        for (Connection conn : allConnections) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        System.out.println("ConnectionPool all connection closed");
        deregisterDriver();
    }
    public void deregisterDriver() {
        try {
            java.sql.Driver driver = DriverManager.getDriver(url);
            DriverManager.deregisterDriver(driver);
        } catch (SQLException e) {
            e.printStackTrace();
        } 
        System.out.println("ConnectionPool deregister driver");
    }
}

请帮助我了解错误并解释我。

1.为什么GC无法释放或为什么他不能做工作?

2.我的ConnectionPool Class有问题?

3.为什么tomcat在我的日志中没有说任何有关OutOfMemoryException的信息(只是崩溃(?

请参阅连接详细信息,显然您有10个连接,并且每个连接保留了CCA 66 MB,如果堆口最高可达660 MB所需的RAM。

我不知道您选择哪些数据,但是当返回连接时,您可能需要关闭所有结果集和语句(为什么要创建自己的池?dbcp,c3p0或commons-pool aiin ain不够好?学习?(,似乎还不够。我真的不知道泳池实施如何正确发布所有资源。

,似乎并不那么直接在多个线程之间共享开放连接Java MySQL JDBC内存泄漏,因此我建议使用工作池解决方案(DBCP(

相关内容

最新更新