内存有限的数据库连接对象行为

时间:2018-04-10 17:09:10

标签: java database jdbc

我已经知道数据库连接应该毫无疑问地关闭,我甚至可以理解为什么:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection,  message from server: "Too many connections" 

这里是抛出上述异常的代码(在我的机器上):

public static void main(String[] args) {
    try {
        for (int i = 0; i < 1000; i++) {
            Connection connection = getConnection();
            Statement st = connection.createStatement();
            st.execute("CREATE TABLE IF NOT EXISTS clients (id INT NOT NULL AUTO_INCREMENT, firstname VARCHAR(50), lastname VARCHAR(50), PRIMARY KEY (id))");
            st.execute("DROP TABLE clients");
        }

    } catch (SQLException e) {
        e.printStackTrace();
    }
}

private static Connection getConnection() throws SQLException {
    return DriverManager.getConnection(bundle.getString("jdbc.url"),
            bundle.getString("jdbc.username"), bundle.getString("jdbc.password"));
}

最终我不得不减少堆大小,上面的代码开始工作。在这些情况下发生了什么?如何在没有任何例外的情况下连续创建连接?

1 个答案:

答案 0 :(得分:2)

我有根据的猜测是底层连接类已经实现了finalize()方法,该方法在对象为GC时清理连接。

如果堆积较大,GC就不会那么努力,所以连接不会被收集。对于较小的堆,GC需要更频繁地收集它们,并且活动连接的限制不会达到最大值。

正确的方法是使用连接数量有限的连接池,这些连接始终保持打开状态,只需从池中借用并返回池中即可。毕竟创建连接是很昂贵的。