Author: markt Date: Fri Sep 21 22:37:49 2012 New Revision: 1388712 URL: http://svn.apache.org/viewvc?rev=1388712&view=rev Log: When the DefaultServlet is under high load, parsing the content-type header generates significant garbage and takes noticeable time. Add a simple cache to address these issues.
Added: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ (with props) tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java - copied, changed from r1388709, tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java - copied, changed from r1388709, tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java Modified: tomcat/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Response.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1388709 Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Response.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Response.java?rev=1388712&r1=1388711&r2=1388712&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Response.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Response.java Fri Sep 21 22:37:49 2012 @@ -20,7 +20,6 @@ package org.apache.catalina.connector; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; -import java.io.StringReader; import java.net.MalformedURLException; import java.security.AccessController; import java.security.PrivilegedAction; @@ -54,8 +53,7 @@ import org.apache.tomcat.util.buf.UEncod import org.apache.tomcat.util.http.FastHttpDateFormat; import org.apache.tomcat.util.http.MimeHeaders; import org.apache.tomcat.util.http.ServerCookie; -import org.apache.tomcat.util.http.parser.AstMediaType; -import org.apache.tomcat.util.http.parser.HttpParser; +import org.apache.tomcat.util.http.parser.MediaTypeCache; import org.apache.tomcat.util.http.parser.ParseException; import org.apache.tomcat.util.net.URL; import org.apache.tomcat.util.res.StringManager; @@ -74,6 +72,9 @@ public class Response // ----------------------------------------------------------- Constructors + private static final MediaTypeCache MEDIA_TYPE_CACHE = + new MediaTypeCache(100); + /** * Compliance with SRV.15.2.22.1. A call to Response.getWriter() if no * character encoding has been specified will result in subsequent calls to @@ -803,10 +804,9 @@ public class Response return; } - AstMediaType m = null; - HttpParser hp = new HttpParser(new StringReader(type)); + String[] m = null; try { - m = hp.MediaType(); + m = MEDIA_TYPE_CACHE.parse(type); } catch (ParseException e) { // Invalid - Assume no charset and just pass through whatever // the user provided. @@ -814,13 +814,12 @@ public class Response return; } - coyoteResponse.setContentTypeNoCharset(m.toStringNoCharset()); + coyoteResponse.setContentTypeNoCharset(m[0]); - String charset = m.getCharset(); - if (charset != null) { + if (m[1] != null) { // Ignore charset if getWriter() has already been called if (!usingWriter) { - coyoteResponse.setCharacterEncoding(charset); + coyoteResponse.setCharacterEncoding(m[1]); isCharacterEncodingSet = true; } } Propchange: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ ------------------------------------------------------------------------------ bugtraq:append = false Propchange: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ ------------------------------------------------------------------------------ bugtraq:label = Bugzilla ID (optional) Propchange: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ ------------------------------------------------------------------------------ --- bugtraq:message (added) +++ bugtraq:message Fri Sep 21 22:37:49 2012 @@ -0,0 +1 @@ +Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=%BUGID% Propchange: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ ------------------------------------------------------------------------------ bugtraq:url = https://issues.apache.org/bugzilla/show_bug.cgi?id=%BUGID% Copied: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java (from r1388709, tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java) URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java?p2=tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java&p1=tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java&r1=1388709&r2=1388712&rev=1388712&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java Fri Sep 21 22:37:49 2012 @@ -30,8 +30,8 @@ public final class ConcurrentCache<K,V> public ConcurrentCache(int size) { this.size = size; - this.eden = new ConcurrentHashMap<>(size); - this.longterm = new WeakHashMap<>(size); + this.eden = new ConcurrentHashMap<K,V>(size); + this.longterm = new WeakHashMap<K,V>(size); } public V get(K k) { Copied: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java (from r1388709, tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java) URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java?p2=tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java&p1=tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java&r1=1388709&r2=1388712&rev=1388712&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java Fri Sep 21 22:37:49 2012 @@ -28,7 +28,7 @@ public class MediaTypeCache { private final ConcurrentCache<String,String[]> cache; public MediaTypeCache(int size) { - cache = new ConcurrentCache<>(size); + cache = new ConcurrentCache<String,String[]>(size); } /** Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1388712&r1=1388711&r2=1388712&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Sep 21 22:37:49 2012 @@ -84,6 +84,12 @@ <bug>53863</bug>: Ensure the the implicit servlets (JSP and default) are marked as override-able when using embedded mode. (markt) </fix> + <fix> + When the <code>DefaultServlet</code> is under heavy load, the HTTP + header parser added to address <bug>52811</bug> generates large amounts + of garbage and uses significant CPU time. A cache has been added that + significantly reduces the overhead of this parser. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org