Bug 58004

Summary: Possible memory leak on ClientAbortException in Ajp
Product: Tomcat 8 Reporter: Bo Madsen <bo.gundersen>
Component: ConnectorsAssignee: Tomcat Developers Mailing List <dev>
Severity: normal CC: bo.gundersen
Priority: P2    
Version: 8.0.23   
Target Milestone: ----   
Hardware: PC   
OS: Linux   
Attachments: Example maven web application

Description Bo Madsen 2015-06-05 09:34:38 UTC
Created attachment 32795 [details]
Example maven web application

When a client drops the connection during a request, a ClientAbortException is thrown. If the web application caches this, and then tries to write to the request outputstream it seems that a memory leak occurs.
I think it is a fairly general scenario where an exception is thrown while serving the request, and then the application tries to write an error response back to the client.

Looking at heap dumps it seems like the bufferedWrites property in AjpNioProcessor grows each time it happens.

I have attached a small web application that shows this issue. The culprit is BigStupidFileServlet that in line 36 writes to the response after having gotten an exception. To execute the sample do:
1) Deploy the web application to a Tomcat, or execute tomcat.example.Main to use the embedded tomcat, and expose it through ajp
2) Start an Apache HTTPD and point it to the Tomcat's ajp port
3) Execute tomcat.example.Breaker with the url of the apache, e.g.: mvn exec:java -Dexec.mainClass="tomcat.example.Breaker"  -Dexec.args="http://localhost:8080/tomcat-example/files/test.bin"
4) Observe that the Tomcat server will run out of memory quickly (on my machine around 6k requests, but it ofcause depends on heap size)
If you run the breaker on a http connector, it will continue running without OOM exceptions.
Comment 1 Remy Maucherat 2015-06-12 15:52:02 UTC
Buffering data in blocking mode seems wrong, it will be fixed in 8.0.24. However, it is really wrong to catch an IOE and expect to write some data ...
Comment 2 Anton Kagan 2015-08-31 05:51:42 UTC
We upgraded to 8.0.24 and still experience high memory usage with APR connector when client downloads a large file.
I can provide heap dumps if needed.