Performance regression issue introduced in JDK 1.6.0_10 but found whilst running performance tests on JDK 1.6.0_14. More info about this problem: //sun.misc.Launcher protected Class findClass(String name) throws ClassNotFoundException { // Check for download before we look for it. If DownloadManager ends up // downloading it, it will add it to our search path before we proceed // to the findClass(). DownloadManager.getBootClassPathEntryForClass(name); //<--- Added in JDK 1.6.0_10 return super.findClass(name); } //sun.misc.Launcher public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { DownloadManager.getBootClassPathEntryForClass(name); //<--- Added in JDK 1.6.0_10 int i = name.lastIndexOf('.'); if (i != -1) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPackageAccess(name.substring(0, i)); } } return (super.loadClass(name, resolve)); } //sun.jkernel.DownloadManager public static String getBootClassPathEntryForClass(final String className) { return getBootClassPathEntryForResource(className.replace('.', '/') + ".class"); //<--- this .replace is causing the regression } //sun.jkernel.DownloadManager public static String getBootClassPathEntryForResource(final String resourceName) { if (debug) log("Entering getBootClassPathEntryForResource(" + resourceName + ")"); if (isJREComplete() || downloading == null || resourceName.startsWith("sun/jkernel")) { //<--- here isJREComplete() is checked which only returns null if (debug) log("Bailing: " + isJREComplete() + ", " + (downloading == null)); return null; } ... Introduction of sun.jkernel.DownloadManager.getBootClassPathEntryForClass(name) in both sun/misc/Launcher.findClass and sun/misc/Launcher.loadClass is causing performance regression. The above code is what is causing this regression, at least for JRockit which ALWAYS isJREComplete() since -Dkernel.download.enabled=false is always set. For every class loaded/to be found the className.replace('.', '/') is being executed, BEFORE checking the isJREComplete() flag which always is TRUE for JRockit. This additional processing causes StringBuilder to be allocated, String.replace() to be called as well as StringBuilder.append() just in order to return null by checking the isJREComplete() flag. Thank you Markus Gronlund Oracle JRockit
|