From 11b1318cad455cb6ce58a0c1e7b98d5a03b369fb Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 20 Sep 2018 21:26:02 -0700 Subject: [PATCH] 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 --- .../org/springframework/boot/loader/jar/Handler.java | 10 ++++++++-- .../org/springframework/boot/loader/jar/JarFile.java | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/Handler.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/Handler.java index 5e9c8075cd..5b23b677bf 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/Handler.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/Handler.java @@ -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 { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java index 9c16b0b74d..dafcd4a2b1 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java @@ -69,6 +69,8 @@ public class JarFile extends java.util.jar.JarFile { private URL url; + private String urlString; + private JarFileEntries entries; private Supplier 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.