United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6888768 DownloadManager causes performance regression in JDK 1.6.0_14
6888768 : DownloadManager causes performance regression in JDK 1.6.0_14

Details
Type:
Bug
Submit Date:
2009-10-06
Status:
Resolved
Updated Date:
2010-12-03
Project Name:
JDK
Resolved Date:
2009-12-14
Component:
performance
OS:
solaris_2.5.1
Sub-Component:
libraries
CPU:
sparc
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u14
Fixed Versions:
6u17-rev

Related Reports
Backport:
Backport:

Sub Tasks

Description
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

                                    

Comments
EVALUATION

Adding feedback from Thomas, I will make the suggested changes and test. 


I think you can simply check isJREComplete() getBootClassPathEntryForClass() to fix this:

//sun.jkernel.DownloadManager
public static String getBootClassPathEntryForClass(final String className) {
	if (isJREComplete()) {
		return null;
	}
	return getBootClassPathEntryForResource(className.replace('.', '/') + ".class"); //<--- this .replace is causing the regression
}
                                     
2009-10-08
WORK AROUND

Either improve checking if DownloadManager should be used BEFORE starting to .replace stuff, or remove calls to DownloadManager altogether.
                                     
2009-10-06



Hardware and Software, Engineered to Work Together