Reputation: 2237
I've been profiling my webapp locally on my pc with VisualVM. I'm pretty certain that I have a small memory leak. After taking a snapshot of the application, I chose the object that had the most instantiated objects and looked through the Allocation Call Tree to see if I could find which class (of mine) was contributing to the 'potential leak'.
I found three of my classes in the tree, and took a look at the method's that were pinpointed.
Here is a snippet of code (a method) from one of my servlets - this method gets the names of session attributes that I want to keep in the session and removes the rest.
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = ds.getConnection();
stmt = conn.createStatement();
HttpSession session = req.getSession();
getExemptSessionAttributes(Customer_Number,rs,stmt,session);
}//try
catch (Exception e) { }
finally {
if (rs != null) {
try { rs.close(); } catch (SQLException e) { ; }
}
if (stmt != null) {
try { stmt.close(); } catch (SQLException e) { ; }
}
if (conn != null) {
try { conn.close(); } catch (SQLException e) { ; }
}
}//finally
}//post
public void getExemptSessionAttributes(int Customer_Number, ResultSet rs, Statement stmt, HttpSession session) {
try {
rs = stmt.executeQuery("Select Name from exemptsessionattributes");
String[] exemptAttributes = null;
int count = 0;
while(rs.next()) {
count++;
}
rs.beforeFirst();
exemptAttributes = new String[count];
count = 0;
while(rs.next()) {
exemptAttributes[count] = rs.getString(1);
count++;
}
session.setAttribute("ExemptSessionAttributes",exemptAttributes);
//garbage collect
exemptAttributes = null;
}//try
catch(Exception e) {}
}//end
//....
The only modification I've made thus far, since profiling my webapp, was the addition of setting the exemptAttributes[] object array to null.
My question is - If a String array (or any object) is set into a session attribute, does that mean that the reference to that object, if not set to null in the code, is still 'referenced' and won't be garbage collected?
Upvotes: 0
Views: 3086
Reputation: 718986
If a String array (or any object) is set into a session attribute, does that mean that the reference to that object, if not set to null in the code, is still 'referenced' and won't be garbage collected?
Not exactly.
If you have set an object as a session attribute, then that object will continue to be reachable (and not garbage collected) for as long as the Session
object is reachable. The Session
object is most likely cached in memory by the servlet infrastructure for a long time.
In this case, assigning null
to the local variable does nothing useful. Firstly, the local is about to go out of scope anyway, and that has the same effect from a GC perspective. Secondly, you've just copied the object reference into a data structure (the Session
object) that has a longer lifetime than the local variable ... so the object will continue to be reachable anyway.
In short, the object continues to be reachable irrespective of whether (or not) you assign null
to the local variable.
Possible way to combat this "leak" include:
null
, orUpvotes: 1
Reputation: 6760
The scope of the exemptAttributes reference (not the actual object referenced by the reference) is the try block in your method. So the answer to your question seems to be a "No".
Could the leak be because you are not destroying the sessions? In other words, if you keep creating new sessions and setting exemptAttributes objects in these sessions, your memory usage will grow unless you are cleaning up old/unused sessions. (you can set a session timeout in web.xml)
Upvotes: 1
Reputation: 47984
To answer your actual question, no, nulling that reference is doing close to nothing. The variable is scoped only to that try {}
block. It goes out of scope as soon as you leave the try and no reference is being held by this class any longer. There are very few 'real' cases where nulling a reference in a method does anything useful for garbage collection. It's going to stick around until the session releases its reference regardless.
The strange way ResultSet
and Statement
are being used, or simply not cleaning up old sessions, seem like better candidates for a problem.
Upvotes: 0