I have a listener method that contains the following code. That method is called multiple times a second. It is, however, causing a memory leak within my application.
I think it may be with the way I am handling the prepared statement (creating new one for each object received). Am I doing anything obviously wrong? Should I be setting the PS to null once it’s used? Are the PSs being retained for some reason?
Also, I’m manually specifying the table name for the PS. Is that redefinition defeating the purpose of using a Prepared Statement entirely?
String text = object.getText();
//determineDb method determines the db for the object based on its content
ArrayList<Topic> toAddList = determineDatabase(text);
if (toAddList.size() > 0) {
int epoch = (int) (System.currentTimeMillis() / 1000);
//Topic class contains DB info, topic name and associated terms
for (Topic a : toAddList) {
try {
pst = con
.prepareStatement("INSERT INTO "
+ a.getTopic()
+ " (created, received, username, text, ignored, retweet, value) VALUES(?, ?, ?, ?, ?, ?, ?)");
pst.setString(1, String.valueOf(object.getCreatedAt().getTime() / 1000));
pst.setString(2, String.valueOf(epoch));
pst.setString(3, object.getUser());
pst.setString(4, text);
pst.setInt(5, 0);
pst.setInt(6, object.isOriginal() ? 1 : 0);
pst.setDouble(7, otherClass.analyzeString(object.getText()));
pst.executeUpdate();
} catch (SQLException ex) {
System.out.println(ex);
}
}
}
You must close your PreparedStatement after you use it, always in a finally block. Any object in java which could correspond to an external resource should always be handled carefully (cleaned up as soon as it is no longer useful). All JDBC resources fall into this category (ResultSet,Statement,Connection).