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

Java 内存有限的数据库连接对象行为,java,database,jdbc,Java,Database,Jdbc,我明白了数据库连接应该毫无疑问地关闭,我甚至明白了为什么: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections" 下面是引发上述异常的代码(在我的机器上): publicstaticvoidmain(字符串[]args)

我明白了数据库连接应该毫无疑问地关闭,我甚至明白了为什么:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection,  message from server: "Too many connections" 
下面是引发上述异常的代码(在我的机器上):

publicstaticvoidmain(字符串[]args){
试一试{
对于(int i=0;i<1000;i++){
Connection=getConnection();
语句st=connection.createStatement();
st.execute(“如果不存在客户端,则创建表(id INT NOT NULL AUTO_INCREMENT,firstname VARCHAR(50),lastname VARCHAR(50),主键(id))”;
st.execute(“DROP TABLE Client”);
}
}捕获(SQLE异常){
e、 printStackTrace();
}
}
私有静态连接getConnection()引发SQLException{
返回DriverManager.getConnection(bundle.getString(“jdbc.url”),
bundle.getString(“jdbc.username”)、bundle.getString(“jdbc.password”);
}

最后我不得不减小堆的大小,上面的代码开始工作。在这些情况下会发生什么?它如何能够在没有任何异常的情况下连续创建连接?

我的猜测是,底层连接类已经实现了
finalize()
方法,该方法在对象被GC调用时清理连接

对于更大的堆,GC的工作不那么努力,因此无法收集连接。对于较小的堆,GC需要更频繁地收集它们,并且活动连接的限制没有达到最大值


正确的方法是使用一个连接池,该连接池中有一定数量的连接,这些连接总是保持打开状态,只是从池中借用并返回到池中。创建连接毕竟是昂贵的。

我有根据地猜测,底层连接类已经实现了
finalize()
方法,该方法在对象被GC调用时清理连接

对于更大的堆,GC的工作不那么努力,因此无法收集连接。对于较小的堆,GC需要更频繁地收集它们,并且活动连接的限制没有达到最大值


正确的方法是使用一个连接池,该连接池中有一定数量的连接,这些连接总是保持打开状态,只是从池中借用并返回到池中。创建连接毕竟是昂贵的。

我真的不确定您的用例。但是,可以使用“设置全局最大连接数=1000”来增加限制;为什么不把
getConnection()
createStatement()
移到循环之外呢?我真的不确定您的用例。但是,可以使用“设置全局最大连接数=1000”来增加限制;为什么不将
getConnection()
createStatement()
移到循环之外呢?对于问题中的特定代码,正确的方法不是使用池,而是将
getConnection()
createStatement()
移到循环之外。你的说法大体上是正确的,所以我给你+1。@Andreas肯定。但他似乎理解连接需要关闭,但不清楚为什么内存大小会影响代码在连接上是否正常工作或达到最大值。哦,是的,你在前两段中出色地阐述了这一点。我是在评论第三段。@Andreas啊,是的,这是一个与他的代码无关的一般性评论。对于问题中的特定代码,正确的方法不是使用池,而是简单地将
getConnection()
createStatement()
移出循环。你的说法大体上是正确的,所以我给你+1。@Andreas肯定。但他似乎理解连接需要关闭,但不清楚为什么内存大小会影响代码在连接上是否正常工作或达到最大值。哦,是的,你在前两段中出色地阐述了这一点。我是在评论第三段。@Andreas啊,是的,那是一个一般性的评论,与他的代码无关。
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"));
}