Reduce GC pressure in JAR handler

Update the JAR `Hander` so that URL `startsWith` checks produce less
garbage. Comparisons are now performed first on the `path` rather than
the full `toString`. URL `toString` operations produce quite a lot of
garbage since a `StringBuilder` is always used.

In addition, we now also cache the JarFile URL toString to save repeated
calculation.

Closes gh-14561
This commit is contained in:
Phillip Webb 2018-09-20 21:26:02 -07:00
parent d0de4657d4
commit 11b1318cad
2 changed files with 17 additions and 2 deletions

View File

@ -92,8 +92,7 @@ public class Handler extends URLStreamHandler {
@Override
protected URLConnection openConnection(URL url) throws IOException {
if (this.jarFile != null
&& url.toString().startsWith(this.jarFile.getUrl().toString())) {
if (this.jarFile != null && isUrlInJarFile(url, this.jarFile)) {
return JarURLConnection.get(url, this.jarFile);
}
try {
@ -104,6 +103,13 @@ public class Handler extends URLStreamHandler {
}
}
private boolean isUrlInJarFile(URL url, JarFile jarFile)
throws MalformedURLException {
// Try the path first to save building a new url string each time
return url.getPath().startsWith(jarFile.getUrl().getPath())
&& url.toString().startsWith(jarFile.getUrlString());
}
private URLConnection openFallbackConnection(URL url, Exception reason)
throws IOException {
try {

View File

@ -69,6 +69,8 @@ public class JarFile extends java.util.jar.JarFile {
private URL url;
private String urlString;
private JarFileEntries entries;
private Supplier<Manifest> manifestSupplier;
@ -301,6 +303,13 @@ public class JarFile extends java.util.jar.JarFile {
}
}
String getUrlString() throws MalformedURLException {
if (this.urlString == null) {
this.urlString = getUrl().toString();
}
return this.urlString;
}
/**
* Return a URL that can be used to access this JAR file. NOTE: the specified URL
* cannot be serialized and or cloned.