On 16/02/2016 16:13, Ty wrote:
> Summary:
> 
> Because of our use case (hundreds of webapps per instance), we cannot
> feasibly upgrade our Tomcat 6 containers to Tomcat 7 or Tomcat 8, due to
> the massive increase in memory the upgrade causes.
> 
> Background:
> 
> We’ve been running Tomcat 6 for several years, on perhaps an unusual scale:
> several dozen Tomcat instances, each running up to a *few hundred webapps*
> in a single container.  (Picture a cloud service provider with several
> products and hundreds of customers, with one dedicated webapp
> per-customer-per-product, resulting in many thousands of web
> applications.  It’s
> not ideal but it’s how the software was designed).  Typical max heap sizes
> per container are 1GB to 4GB depending on utilization, and max container
> startup times are in the neighborhood of 5 to 10 minutes.
> 
> ·         When Tomcat 7 was released, our testing showed a 10-to-20-fold
> increase in memory consumption and a 3-to-5-fold increase in startup time
> for our test case (100 deployed webapps).  After some digging we determined
> that these increases were related to JAR scanning
> (tomcat.util.scan.DefaultJarScanner).

JAR scanning should be transient. What was it that was causing the 10-20
fold increase?

> ·         When Tomcat 8 was released, we noted that it included a
> “whitelist” version of the jarsToSkip Property, jarsToScan.  Our hopes were
> high that we could skip from Tomcat 6 to Tomcat 8, but our test case (again
> 100 deployed webapps) quickly deflated those hopes:  similar startup times
> but at least a *30-fold increase in memory consumption*, regardless of how
> we configure jarsToScan or jarsToSkip.
> 
> ·         A heap dump analysis showed that the Tomcat 8 memory increase was
> largely due to the size/count of
> org.apache.catalina.webresources.JarResourceSet objects.

Those are only going to be created when a JAR is found that contains
META-INF/resources. The spec requires Tomcat to expose those as static
resources and that requires plumbing. Note Tomcat 6 will just ignore
these because the spec is to old for this feature.

> We attempted to
> reduce this by setting the Context/Resources@cachingAllowed atttribute to
> “false” and also tried to tune the “cacheMaxSize” and “cacheObjectMaxSize”
> attributes.

Those attributes should have no impact on the number or size of the
JarResourceSet instances.

> The only effect that came from these changes was a change in
> the object that took up all the space:  instead of
> org.apache.catalina.webresources.JarResourceSet objects, they are
> org.apache.catalina.webresources.StandardResourceSet objects, taking up
> roughly the same amount of space.

Strange. Very strange.

> Question:
> 
> Is there anything else we can adjust to make Tomcat 8’s memory consumption
> closer to that of Tomcat 6’s, for our use case?

It is hard to see exactly what is going on here. The symptoms you
describe and the resulting changes with configuration are not consistent
with how I would expect Tomcat to behave nor can I see how it might
behave in the way described.

> If not, we are faced with
> either running Tomcat 6 past its EOL, or possibly maintaining a very large
> jarsToSkip blacklist in Tomcat 7 (until its EOL).  It is not economically
> feasible for us to increase the physical memory of our servers by 30x so we
> can run Tomcat 8.
> 
> Test procedure:
> 
> 
>    - Create a "dummy" webapp (using default Maven archetype) named test.war
>    - Add several popular Maven dependencies such that the total size of the
>    JARs in WEB-INF/lib is about 30MB

Can you provide the sample project? It makes sense to ensure we are
working from the same baseline. I wonder if the libraries themselves are
a factor here.

>    - Download the latest versions of Tomcat 6, 7, and 8.
>    - Set Java environment variables for a JMX listener and a 3GB max heap
>    - Make 100 copies of test.war (test1.war, test2.war, …, test100.war) and
>    drop them in /webapps.
>    - Start the container, note the reported startup time, perform an
>    explicit major GC, and note the heap utilization.
>    - Run each test several times and average the results

That is a nice simple test we should be able to repeat.

> Test results:
> 
> Case 1 (baseline):
> 
> 
> 
> +---------+--------------+---------------------------+
> | version | startup time | heap usage after major GC |
> +---------+--------------+---------------------------+
> | tomcat6 | 36,711ms     | 21,163,288                |
> | tomcat7 | 104,517ms    | 489,992,264               |
> | tomcat8 | 156,094ms    | 1,010,512,568             |
> +---------+--------------+---------------------------+
> 
> 
> Case 2 (Tomcat 7 and 8 with “jarsToSkip=*”)
> 
> +---------+--------------+---------------------------+
> | version | startup time | heap usage after major GC |
> +---------+--------------+---------------------------+
> | tomcat6 | 36,711ms     | 21,163,288                |
> | tomcat7 | 38,979ms     | 72,359,840                |
> | tomcat8 | 52,040ms     | 633,682,336               |
> +---------+--------------+---------------------------+

>From those figures my impression is that we should be able to do
something about the memory. The start-up time with JAR scanning is what
it is. Without JAR scanning there might be scope for improvement.

Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to