Article:
  Two Servlet Filters Every Web Application Should Have
Subject:   GZIP memory leak and content length problems
Date:   2004-08-18 07:29:21
From:   krem
Hi,


I found few issues using the GZIP compression filter. I'll show the solutions that worked for me.


I am using Jetty/4.2.21 WEB server and servlet container running on Java VM (build 1.4.2_05-b04).
The OS is Win 2000.


After deploying the GZIP compression filter and running my stress test I found a strange memory leak.
The memory usage of the Java VM started growing rapidly. No java.lang.OutOfMemoryError has been thrown after the VM memory reached the maximum heap size (which was set to 64MB). After the memory usage reached about 600MB I had to stop the stress test because my OS complained about low virtual memory. I suppose there is a memory leak in the native gzip library which is used by the VM.


I am not sure if this is a general issue or it is just related to the server I am using, but I found a solution.


I have rewritten the doFilter method as follows:




public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if (req instanceof HttpServletRequest) {

HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String ae = request.getHeader("accept-encoding");
if (ae!=null && ae.indexOf("gzip")!=-1) {
GZIPResponseWrapper wrappedResponse = new GZIPResponseWrapper(response);
try {
chain.doFilter(req, wrappedResponse);
}
catch (ServletException ex) {throw ex;}
catch (IOException ex) {throw ex;}
catch (Exception ex) {throw new ServletException(ex);} // this is in case a Servet caused an internal error
finally {
wrappedResponse.finishResponse();
}
}
else chain.doFilter(req, res);

}
}




I am using the finally statement to ensure that the finishResponse() method gets called in all cases.


Second, I have rewritten the GZIPResponseStream.close() method as follows:




public void close() throws IOException {
if (closed) throw new IOException("This output stream has already been closed");
//
gzipstream.finish();
gzipstream.flush();
gzipstream.close(); //!!!
//
byte[] bytes = baos.toByteArray();
response.setContentLength(bytes.length);
response.addHeader("Content-Encoding","gzip");
output.write(bytes);
output.flush();
output.close();
closed = true;
}




Closing the gzipstream fixed the memory leak.


The second issue was about the content length. The browser acted strangely. Data seemed to be corrupted. Sometimes the css styles disapeared, sometimes not.


The resolution is in the GZIPResponseStream.close() method as written above. I had to change the line:



response.addHeader("Content-Length", Integer.toString(bytes.length));


to



response.setContentLength(bytes.length);



I hope this post is somehow helpful and I really hope somebody understood my poor English:)


Have a nice day,
krem.

Full Threads Oldest First

Showing messages 1 through 5 of 5.

  • GZIP memory leak and content length problems
    2008-11-08 21:05:50  corlettk [View]

    Krem,

    I've incorporated your enhancements. I had the same memory leak issue, due to taglib throwing AIOBEs.

    The memory leak appears to be fixed now, along with the root cause of those pesky AIOBEs.

    Thank you. Cheers. Keith.
  • GZIP memory leak and content length problems
    2007-07-20 07:26:15  ManfredJS [View]

    Hi,

    I downloaded the jspbook.jar file from http://www.jspbook.com/.
    Does anybody know if the above mentioned memory leak has already been solved in the latest jspbook.jar file, or should I still make the above changes myself?

    Kind regards,
    Manfred
  • GZIP memory leak and content length problems
    2004-10-13 05:57:23  saikinnera [View]

    Hi Krem,
    I am working on compressing the content using GZIPOutputStream.On my local machine everything is working fine. Using struts on weblogic 8.1. But when I try to get that page from another machine pointing my local server, I am getting a FileDownload dialog and if I open it, there is binary content. Could you please suggest anything on this.

    Thanks,
    sai
    • GZIP memory leak and content length problems
      2006-07-23 23:26:04  CheenuInventor [View]

      After 3 days analysis on Weblogic 8.1 i have found the solution for this problem. If guys need the solution contact me at chinu_en@yahoo.com. Since i really need to know how many have come across this situation.
      • GZIP memory leak and content length problems
        2007-01-18 05:49:27  ShriniMailNSrinivasan@gmail.com [View]

        solution :
        1. Dont try to compress html files from weblogic 8 (not tried with any other weblogic version).
        2. Dont give multiple route of mapping to a filter in web.xml in weblogic 8.

        To be more clear on second point ,

        <filter-mapping>
        <filter-name>CompressionFilter</filter-name>
        <url-pattern>/servlet</url-pattern>
        </filter-mapping>

        <filter-mapping>
        <filter-name>CompressionFilter</filter-name>
        <servlet-name>Index</servlet-name>
        </filter-mapping>

        <servlet-mapping>
        <servlet-name>Index</servlet-name>
        <url-pattern>/servlet</url-pattern>
        </servlet-mapping>

        All the request has a url patern "/servlet" passes through CompressionFilter.
        All the request will reach the Index Servlet will also passes through CompressionFilter.
        If a request matches both the above condition then response will be compressed twice.
        Thus creates the prob of FileDownload dialog or junk chars shown.
        This will not happen in tomcat.