Summary: | memory leak--ServerCookie | ||
---|---|---|---|
Product: | Tomcat 9 | Reporter: | sunqi <sunqi800> |
Component: | Catalina | Assignee: | Tomcat Developers Mailing List <dev> |
Status: | RESOLVED FIXED | ||
Severity: | major | CC: | gehill_cn, huxing.zhang, jan0michael |
Priority: | P2 | ||
Version: | 9.0.0.M9 | ||
Target Milestone: | ----- | ||
Hardware: | All | ||
OS: | All |
Description
sunqi
2016-07-27 06:31:47 UTC
ps we use async servlet,(If using Servlet 3.0 asynchronous processing, a good default is to use the larger of maxThreads and the maximum number of expected concurrent requests (synchronous and asynchronous),it is much larger than the default value of 200. We saw two issues in this case: 1) the size of org.apache.tomcat.util.http.Cookies#scookies array never gets shrunk after recycle, once it is dynamically resized. 2) the number of org.apache.tomcat.util.http.ServerCookie object can be dramatically large, which might lead to memory leak. A maxHeaderSize of 8k has limit the number of ServerCookie object to no more than 2k, assuming each cookie is 4 bytes (e.g. 'a=b;'). This may have limited impact for a web application with low concurrency. However, for a heavily concurrent, NIO-based connector, this may have a huge impact. Suppose a malicious client is sending 2k concurrent request, each sending 2k cookies, at tomcat side there will be 2k * 2k = 4m ServerCookie objects. Since the default maxConnection value is 10k for NIO, there can be at most 20m Server Cookies objects, and cannot be recycled because of 1). Proposal: 1) We propose to shrink the org.apache.tomcat.util.http.ServerCookie object array back to its initial size after recycling org.apache.tomcat.util.http.Cookies object. 2) We propose to add a maxCookieCount configuration to limit the number of cookie to process. When exceeding the limit, extra data are ignored and a warning message is logged. The default value of maxCookieCount shall be unlimited to be compatible with current behavior, and configurable via server.xml. We are currently working on a patch of 1) and 2). > A maxHeaderSize of 8k has limit the number of ServerCookie object to no more than 2k Correction: We have just observed many 4k ServerCookie object array in org.apache.tomcat.util.http.Cookies#scookies in our latest heap dump. Since spec [1] does not require cooke name and cookie value to be non-empty, given maxHeaderSize=8k, the max number of ServerCookie object in a request will be 4k, if if cookie string is '=;=;=;=;=;...'. We argue the growing strategy here that the number of ServerCookie object should have an upper limit, which is maxHeaderSize / 2. For example, if maxHeaderSize is 5k, then the number of ServerCookie object should be no more than 2.5k, hence the growing from 2k -> 4k will be unnecessary. [1] https://tools.ietf.org/html/rfc6265#section-4.2.2 *** Bug 59911 has been marked as a duplicate of this bug. *** 59911 has a patch idea. *** Bug 59926 has been marked as a duplicate of this bug. *** The proposed patch in 59926 is against tomcat 9 trunk. I did some testing using: http://browsercookielimits.squawky.net/ Focusing on max cookies per domain, the results are: FireFox + Win = 150 FireFox + OSX = 150 Chrome + Win = 180 Chrome + OSX = 180 IE 11 + Win = 50 Safari + OSX = unlimited? Therefore, I think enforcing a default limit of 200 is reasonable. That should make the patch simpler since I don't see the need for tracking the attainableMaxCookieCount with this default. This has been fixed in the following branches: - 9.0.x for 9.0.0.M10 onwards - 8.5.x for 8.5.5 onwards - 8.0.x for 8.0.37 onwards - 7.0.x for 7.0.71 onwards - 6.0.x for 6.0.46 onwards Thanks for the patch suggestion. It was used, and back-ported, with a few minor changes. Does the cookies-per-domain increase if a subdomain is being used? For example, will the browser separately limit cookies for example.com to 150 but also foo.example.com to another 150, so that foo.example.com could potentially get 300 cookies? |