我有一个线程,用一些值执行和更新数据库。我注释掉了对数据所做的所有操作,并留下了您可以在下面看到的行。用你看到的线条运行程序时,我得到了内存泄漏。
这就是VisualVM中的样子
Mysql类
public ResultSet executeQuery(String Query) throws SQLException {
statement = this.connection.createStatement();
resultSet = statement.executeQuery(Query);
return resultSet;
}
public void executeUpdate(String Query) throws SQLException {
Statement tmpStatement = this.connection.createStatement();
tmpStatement.executeUpdate(Query);
tmpStatement.close();
tmpStatement=null;
}
线程文件
public void run() {
ResultSet results;
String query;
int id;
String IP;
int port;
String SearchTerm;
int sleepTime;
while (true) {
try {
query = "SELECT * FROM example WHERE a='0'";
results = this.database.executeQuery(query);
while (results.next()) {
id = results.getInt("id");
query = "UPDATE example SET a='1' WHERE id='"
+ id + "'";
SearchTerm=null;
this.database.executeUpdate(query);
}
results.close();
results = null;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在研究网络后,许多其他人发生了这个问题,
https://forum.hibernate.org/viewtopic.php?f=1&t=987128
Is bone cp or mysql.jdbc.JDBC4Connection known for leaking?
还有一些如果你google“jdbc4resultset memory leak”
答案 0 :(得分:7)
泄漏是你的,而不是MySQL。你没有结束陈述。
您的方法设计很差。它应该关闭语句,它应该返回一些在语句结束后仍然存在的东西,例如CachedRowSet
。
否则根本不存在。它只有三行,并且它不支持查询参数,所以它并没有太多用处。我会删除它。
您似乎还有statement
作为实例成员,这种情况很少发生。它应该是方法的本地。目前,您的代码甚至不是线程安全的。
您还应该关闭finally块中的ResultSet
以确保它已关闭。同上Statement
。
答案 1 :(得分:2)
确保明确关闭数据库连接。