Bug 61212 - Slow application boot time due to constant jar file content read
Summary: Slow application boot time due to constant jar file content read
Status: RESOLVED DUPLICATE of bug 60963
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.5.15
Hardware: PC All
: P2 normal with 5 votes (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-06-23 12:53 UTC by Adrianas
Modified: 2018-02-03 21:38 UTC (History)
1 user (show)



Attachments
Profile Before (561.19 KB, image/png)
2017-06-23 12:53 UTC, Adrianas
Details
Profile After (368.22 KB, image/png)
2017-06-23 12:53 UTC, Adrianas
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Adrianas 2017-06-23 12:53:06 UTC
Created attachment 35071 [details]
Profile Before

We do have relativelly big spring based application with ~250mb of jars.

After migrating from tc 7 to tc 8 application boot time significantly increased. Seems that most of the time is taken by a constant call to java.util.jar.JarFile.getJarEntry. 

Looks like tc8 class/resource loaded on each ClassLoader.loadClass(String) iterates throught all jars and asked each jar if resource exists instead of caching jar content once in memmory.

tc 8 has the ability to read jar contens only once but to enable it we had to extend org.apache.catalina.webresources.StandardRoot iwth custom implementation.

After change total time spent on org.apache.catalina.loader.WebappClassLoaderBase.loadClass(String) dropped from 87sec to 39sec. It was 40+sec of time wasted on constant jar content check.

package org.apache.catalina.webresources;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResourceSet;

/**
 * Created by adi on 09/06/2017.
 */
public class CustomStandardRoot extends org.apache.catalina.webresources.StandardRoot {

    @Override
    protected void startInternal() throws LifecycleException {
        super.startInternal();
        for (WebResourceSet webResourceSet : getClassResources()) {
            if (webResourceSet instanceof AbstractArchiveResourceSet) {
                // Load Jar Content into Memory
                ((AbstractArchiveResourceSet)webResourceSet).getArchiveEntries(false);
            }
        }
    }
}

and register custom implementation in TOMCAT_HOME/conf/context.xml 
<?xml version="1.0" encoding="UTF-8"?>
Context containerSciFilter="org.apache.tomcat.websocket.server.WsSci">
...
	<Resources cachingAllowed="true" className="org.apache.catalina.webresources.CustomStandardRoot"/>	
...
</Context>
Comment 1 Adrianas 2017-06-23 12:53:41 UTC
Created attachment 35072 [details]
Profile After
Comment 2 Adrianas 2017-06-23 13:05:46 UTC
We do have relativelly big spring based application with ~250mb of jars.

After migrating from tc 7 to tc 8 application boot time significantly increased. Seems that most of the time is taken by a constant call to java.util.jar.JarFile.getJarEntry. 

Looks like tc8 class/resource loader on each ClassLoader.loadClass(String) iterates through all jars and asks each jar if resource exists (instead of caching jar content once in memory).

tc 8 has the ability to read jar contens only once but to enable it we had to extend org.apache.catalina.webresources.StandardRoot with custom implementation.

After change total time spent on org.apache.catalina.loader.WebappClassLoaderBase.loadClass(String) dropped from 87sec to 39sec. It was 40+sec of time wasted on constant jar content check.

package org.apache.catalina.webresources;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResourceSet;

/**
 * Created by adi on 09/06/2017.
 */
public class CustomStandardRoot extends org.apache.catalina.webresources.StandardRoot {

    @Override
    protected void startInternal() throws LifecycleException {
        super.startInternal();
        for (WebResourceSet webResourceSet : getClassResources()) {
            if (webResourceSet instanceof AbstractArchiveResourceSet) {
                // Load Jar Content into Memory
                ((AbstractArchiveResourceSet)webResourceSet).getArchiveEntries(false);
            }
        }
    }
}

and register custom implementation in TOMCAT_HOME/conf/context.xml 
<?xml version="1.0" encoding="UTF-8"?>
Context containerSciFilter="org.apache.tomcat.websocket.server.WsSci">
...
	<Resources cachingAllowed="true" className="org.apache.catalina.webresources.CustomStandardRoot"/>	
...
</Context>
Comment 3 Mark Thomas 2017-06-23 18:59:16 UTC

*** This bug has been marked as a duplicate of bug 60963 ***
Comment 4 Adrianas 2017-07-06 12:28:57 UTC
We face this issue with unpacked war so I'm not sure if this is a duplicate
Comment 5 Mark Thomas 2017-07-06 12:40:35 UTC
Slow startup issues with unpacked web applications are most likely a configuration issue.

See https://wiki.apache.org/tomcat/HowTo/FasterStartUp and follow up on the users list if you need further assistance.
Comment 6 Adrianas 2017-07-06 12:52:52 UTC
We checked all FasterStartUp hints none of them gave material improvement.