Reputation: 88
I'm trying to analyze a heap dump to find a memory leak for the first time. I'm opening up the heap dump using MAT and right away it's pretty clear it's one object? that is taking up almost the entire heap and it's a sql class com.mysql.cj.jdbc.ConnectionImpl.
Since sql is really used in only one part of my code it basically has to be something with this small bit of code here...
static Connection getDBconn() {
Connection conn = null;
while (conn == null) {
try {
conn = DriverManager.getConnection(serverURL, user, pass);
} catch (SQLException e) {
Logger.logError(e);
}
}
return conn;
}
static void update(String sql) {
while (currConn == null)
currConn = getDBconn();
boolean error = false;
do {
try {
currConn.createStatement().executeUpdate(sql);
} catch (SQLException e) {
try {
currConn.close();
} catch (SQLException e1) {
Logger.logError(e1);
}
currConn = getDBconn();
Logger.logError(e);
error = true;
}
} while (error);
}
static ResultSet query(String sql) {
while (currConn == null)
currConn = getDBconn();
ResultSet rs = null;
while (rs == null) {
try {
rs = currConn.createStatement().executeQuery(sql);
} catch (SQLException e) {
try {
currConn.close();
} catch (SQLException e1) {
Logger.logError(e1);
}
currConn = getDBconn();
Logger.logError(e);
}
}
return rs;
}
What this code is supposed to do is basically wrap query/update statements inside some methods to ensure that each command is always carried out eventually, even when an error comes up. My program will be running for long amounts of time with many requests, and i want to ensure it deals with all possible problems automatically without interrupting the program.
What i have written will work for about an hour or so and then i'll get a out of memory error even when i have my heap set to like 8gb which is obviously overkill. I should also note i'm not getting any sql errors so it's not even getting into the catch blocks. Clearly there is some sort of leak with this code but i'm having trouble figuring out what it could be. Any advice would be appreciated and i can provide more information on the heap dump if needed.
Upvotes: 1
Views: 950
Reputation: 58772
You are getting connection when you don't need it twice
try {
currConn.close();
} catch (SQLException e1) {
Logger.logError(e1);
}
--> currConn = getDBconn();
Logger.logError(e);
Just remove currConn = getDBconn()
after currConn.close();
and you won't have connection leak.
Better yet, close connection on finally even if no error occurred:
try {
rs = currConn.createStatement().executeQuery(sql);
} catch (SQLException e) {
Logger.logError(e);
finally{
try {
currConn.close();
} catch (SQLException e1) {
Logger.logError(e1);
}
}
Also create a method to prevent code duplication and different implementation of closing connection.
Upvotes: 0