When an application stores an object into the session and then the
application is reloaded using Tomcat Web Application Manager, the
classloader cannot be garbage collected. As a result, the
"OutOfMemoryError: PermGen space" error occurs after several reloads.

To illustrate the issue, you can find an example below.
Thanks in advance :-)


1. The EvilClass class whose instances are stored into the session:

public class EvilClass implements Serializable {

    // Eat 100 MB from the JVM heap to see that the class is not
garbage collected
    protected static final byte[] MEM = new byte[100 << 20];

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}


2. Servlet which stores EvilClass instances into session

public class TestServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException {
        EvilClass obj = new EvilClass();
        obj.setValue(req.getRequestURI());
        req.getSession().setAttribute("test", obj);
        getServletContext().log("Attribute stored to session " + obj);
    }

}


3. web.xml part which maps the servlet to an URL

<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>test.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>


Steps to reproduce the issue:
1. Copy application WAR to the webapps directory.
2. Start Apache Tomcat.
3. Hit TestServlet.
4. Check Heap/PermGen size using Java VisualVM.
5. Reload the application thru Tomcat Web Application Manager.
6. Hit TestServlet again.
7. Perform GC and check Heap/PermGen size again.


Environment:
Apache Tomcat version: 7.0.50
OS: Windows 7 64
JVM: Java HotSpot(TM) 64-Bit Server VM (23.6-b04, mixed mode)
Java: version 1.7.0_10, vendor Oracle Corporation

Reply via email to