【发布时间】:2025-12-14 17:35:01
【问题描述】:
我有一个线程来执行和更新带有一些值的数据库。我注释掉了对数据所做的所有操作,只留下了您可以在下面看到的行。在使用您在下面看到的行运行程序时,我遇到了内存泄漏。
这就是它在 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?
如果你用谷歌搜索“jdbc4resultset 内存泄漏”,还有更多
【问题讨论】:
-
每个单独的线程如何获取它的
Connection对象?很有可能问题就在那里 -
每次都创建一个新语句会产生很多开销。查看
PreparedStatement以减少开销(处理和网络)、提高性能并提高安全性(自动转义特定于数据库的关键字以防止 SQL 注入)。 -
看起来您正在泄漏
ResultSet实例。您可以进行堆转储并查看它们被占用的位置。 -
我很确定您在某处有问题...我每天都使用 mysql jdbc 4.0 驱动程序(实际上每天使用数千次,因为它在生产代码中)并且没有任何已知的泄漏是由它引起的。
标签: java mysql jdbc memory-leaks