Java 7 ClassLoader performance improvements
Use Java 7 `registerAsParallelCapable` and `getClassLoadingLock` methods when possible. This should improve performance when running on JDK 7+ whilst still remaining JDK 6 compatible. Closes gh-1284
This commit is contained in:
parent
da5c36c3a9
commit
4f440fcbb9
|
|
@ -36,8 +36,19 @@ import org.springframework.boot.loader.jar.JarFile;
|
||||||
*/
|
*/
|
||||||
public class LaunchedURLClassLoader extends URLClassLoader {
|
public class LaunchedURLClassLoader extends URLClassLoader {
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
ClassLoader.registerAsParallelCapable();
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodError ex) {
|
||||||
|
// Not available on earlier JDKs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final ClassLoader rootClassLoader;
|
private final ClassLoader rootClassLoader;
|
||||||
|
|
||||||
|
private final LockProvider lockProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link LaunchedURLClassLoader} instance.
|
* Create a new {@link LaunchedURLClassLoader} instance.
|
||||||
* @param urls the URLs from which to load classes and resources
|
* @param urls the URLs from which to load classes and resources
|
||||||
|
|
@ -46,6 +57,17 @@ public class LaunchedURLClassLoader extends URLClassLoader {
|
||||||
public LaunchedURLClassLoader(URL[] urls, ClassLoader parent) {
|
public LaunchedURLClassLoader(URL[] urls, ClassLoader parent) {
|
||||||
super(urls, parent);
|
super(urls, parent);
|
||||||
this.rootClassLoader = findRootClassLoader(parent);
|
this.rootClassLoader = findRootClassLoader(parent);
|
||||||
|
this.lockProvider = createLockProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
private LockProvider createLockProvider() {
|
||||||
|
try {
|
||||||
|
ClassLoader.class.getMethod("getClassLoadingLock", String.class);
|
||||||
|
return new Java7LockProvider();
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException ex) {
|
||||||
|
return new LockProvider();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader findRootClassLoader(ClassLoader classLoader) {
|
private ClassLoader findRootClassLoader(ClassLoader classLoader) {
|
||||||
|
|
@ -126,7 +148,7 @@ public class LaunchedURLClassLoader extends URLClassLoader {
|
||||||
@Override
|
@Override
|
||||||
protected Class<?> loadClass(String name, boolean resolve)
|
protected Class<?> loadClass(String name, boolean resolve)
|
||||||
throws ClassNotFoundException {
|
throws ClassNotFoundException {
|
||||||
synchronized (this) {
|
synchronized (this.lockProvider.getLock(this, name)) {
|
||||||
Class<?> loadedClass = findLoadedClass(name);
|
Class<?> loadedClass = findLoadedClass(name);
|
||||||
if (loadedClass == null) {
|
if (loadedClass == null) {
|
||||||
Handler.setUseFastConnectionExceptions(true);
|
Handler.setUseFastConnectionExceptions(true);
|
||||||
|
|
@ -222,4 +244,27 @@ public class LaunchedURLClassLoader extends URLClassLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy used to provide the synchronize lock object to use when loading classes.
|
||||||
|
*/
|
||||||
|
private static class LockProvider {
|
||||||
|
|
||||||
|
public Object getLock(LaunchedURLClassLoader classLoader, String className) {
|
||||||
|
return classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java 7 specific {@link LockProvider}.
|
||||||
|
*/
|
||||||
|
private static class Java7LockProvider extends LockProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getLock(LaunchedURLClassLoader classLoader, String className) {
|
||||||
|
return classLoader.getClassLoadingLock(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue