katura
katura

Reputation: 2237

May have a memory leak in Java webapp - have question about garbage collection and session attributes

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

Answers (3)

Stephen C
Stephen C

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:

  • don't put a reference to the object into a session attribute,
  • set the session attribute to null, or
  • adjust the web container's session caching strategy so that idle sessions are dropped from the cache.
  • implement a scheme to invalidation sessions (e.g. log users out) after a period of idleness.

Upvotes: 1

Amol Katdare
Amol Katdare

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

Affe
Affe

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

Related Questions