Summary: | Memory consumption | ||
---|---|---|---|
Product: | Tomcat 8 | Reporter: | Jaroslav Kamenik <jaroslav> |
Component: | Catalina | Assignee: | Tomcat Developers Mailing List <dev> |
Status: | RESOLVED FIXED | ||
Severity: | enhancement | ||
Priority: | P2 | ||
Version: | 8.0.18 | ||
Target Milestone: | ---- | ||
Hardware: | PC | ||
OS: | Linux |
Description
Jaroslav Kamenik
2015-02-23 09:29:12 UTC
No analysis provided to suggest the proposed merging is even possible. (Chances are it isn't without a lot of complexity else the JVM would have already done it.) I tracked-down a bunch of similar issues in our own application several years ago, and it turned out that the application framework (Struts 1, in our case), was the culprit. We never found that Tomcat was a significant source of "duplicate" strings. I have found the similar simptoms that the multiple "jar" strings are allocated by tomcat WebappClassLoader. The problem stems from usage of java.net.URL(String spec) constructor for ResourceEntry. The java.net.URL(String) parses the source and splits the "scheme" part, and by forcibly converting it toLowerString a separate copy of "jar" string is created for each new ResourceEntry. The problem can be solved by using different java.net.URL(String protocol, String host, int port, String file) constructor, where "jar" can by passed as a constant which could be shared by all instances of created URL classes. I have created a small home test for Tomcat 7.0.82, which by means of visualvm/heapdump showed that "jar" strings are realy shared among different instances of URLs. The code for example for Tomcat 7.0.82 is located in org.apache.tomcat.buf.UriUtil.java, the commented lines are from previous version: public static URL buildJarUrl(String fileUrlString, String entryPath) throws MalformedURLException { String safeString = makeSafeForJarUrl(fileUrlString); StringBuilder sb = new StringBuilder(); // sb.append("jar:"); sb.append(safeString); sb.append("!/"); if (entryPath != null) { sb.append(makeSafeForJarUrl(entryPath)); } // return new URL(sb.toString()); return new URL("jar", null, -1, sb.toString()); } Thanks for the patch - it looks reasonable to me. My testing shows 7.0.x benefits from this more, possibly due to the resources refactoring in 8.0.x onwards. Fixed in: - trunk for 9.0.3 onwards - 8.5.x for 8.5.25 onwards - 8.0.x for 8.0.49 onwards - 7.0.x for 7.0.84 onwards |