[jboss-jira] [JBoss JIRA] (JBCL-185) BaseClassLoader.loadClass() is slow under load

Aaron Ogburn (JIRA) jira-events at lists.jboss.org
Mon Oct 1 13:22:03 EDT 2012


    [ https://issues.jboss.org/browse/JBCL-185?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12722995#comment-12722995 ] 

Aaron Ogburn edited comment on JBCL-185 at 10/1/12 1:20 PM:
------------------------------------------------------------

The reason the class is not cached appears to be the following portion of BaseClassLoaderDomain.loadClass:

         Thread thread = Thread.currentThread();
         ClassLoadingTask task = new ClassLoadingTask(name, classLoader, thread);
         ClassLoaderManager.scheduleTask(task, loader, false);
         Class<?> result = ClassLoaderManager.process(thread, task);
         ClassCacheItem item = globalClassCache.get(path);
         if (item != null)
            item.clazz = result;
         return result;


The resulting class is only added to a preexisting ClassCacheItem.  No ClassCacheItem was created for this previously on this domain.  TRACE logging has shown that the parent domain is finding the loader in this case and creating initially creating/adding a ClassCacheItem here instead through findLoaderInExports.

I've attached a test case that I think replicates this issue with a failure to cache in a child domain.  It currently fails but the testcase passes after I implement the following change to BaseClassLoaderDomain.loadClass that creates and adds a ClassCacheItem regardless of whether or not an entry already exists:

         Thread thread = Thread.currentThread();
         ClassLoadingTask task = new ClassLoadingTask(name, classLoader, thread);
         ClassLoaderManager.scheduleTask(task, loader, false);
         Class<?> result = ClassLoaderManager.process(thread, task);
         ClassCacheItem item = new ClassCacheItem(loader);
         item.clazz = result;
         globalClassCache.put(path, item);
         if (trace && item.clazz != null)
               log.trace(this + " cached " + name + " in global class cache ");
         return result;

                
      was (Author: aogburn):
    The reason the class is not cached appears to be the following portion of BaseClassLoaderDomain.loadClass:

      Loader loader = findLoader(classLoader, path, allExports, findInParent);
      if (loader != null)
      {
         Thread thread = Thread.currentThread();
         ClassLoadingTask task = new ClassLoadingTask(name, classLoader, thread);
         ClassLoaderManager.scheduleTask(task, loader, false);
         Class<?> result = ClassLoaderManager.process(thread, task);
         ClassCacheItem item = globalClassCache.get(path);
         if (item != null)
            item.clazz = result;
         return result;
      }


The resulting class is only added to a preexisting ClassCacheItem.  No ClassCacheItem was created for this previously on this domain.  TRACE logging has shown that the parent domain is finding the loader in this case and creating initially creating/adding a ClassCacheItem here instead through findLoaderInExports.

I've attached a test case that I think replicates this issue with a failure to cache in a child domain.  It currently fails but the testcase passes after I implement the following change to BaseClassLoaderDomain.loadClass that creates and adds a ClassCacheItem regardless of whether or not an entry already exists:

         Thread thread = Thread.currentThread();
         ClassLoadingTask task = new ClassLoadingTask(name, classLoader, thread);
         ClassLoaderManager.scheduleTask(task, loader, false);
         Class<?> result = ClassLoaderManager.process(thread, task);
         ClassCacheItem item = new ClassCacheItem(loader);
         item.clazz = result;
         globalClassCache.put(path, item);
         if (trace && item.clazz != null)
               log.trace(this + " cached " + name + " in global class cache ");
         return result;

                  
> BaseClassLoader.loadClass() is slow under load
> ----------------------------------------------
>
>                 Key: JBCL-185
>                 URL: https://issues.jboss.org/browse/JBCL-185
>             Project: JBoss ClassLoader
>          Issue Type: Enhancement
>          Components: ClassLoader
>    Affects Versions: JBossCL.2.0.9.GA 
>         Environment: -JBoss Enterprise Application Platform (EAP) 5.1.2
> -JBossCL 2.0.9.GA
>            Reporter: Aaron Ogburn
>            Assignee: Ales Justin
>         Attachments: BaseClassLoader.java, JBCL-185.patch, JBCl-185testcase.tar.gz
>
>
> Classloader performance dropped from EAP 4.3 to 5.  Thread dumps show threads facing contention in the classloader:
>    java.lang.Thread.State: BLOCKED (on object monitor)
> 	at org.jboss.classloader.spi.base.BaseClassLoader.doLoadClass(BaseClassLoader.java:495)
> 	- waiting to lock <0x80e22960> (a org.jboss.classloader.spi.base.BaseClassLoader)
> 	at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:447)
> 	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
> 	at org.jboss.classloading.spi.DelegatingClassLoader.loadClass(DelegatingClassLoader.java:87)
> 	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
> 	at org.jboss.util.loading.DelegatingClassLoader.loadClass(DelegatingClassLoader.java:97)
> 	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
> These are repeat lookups.  The thread and classloader trace logging show that these look ups are not returning cached values from checkCacheAndBlackList() and so they are having to go progress through doLoadClass() and the baseclassloderdomain to finally return the class from another classloaders cache.  This is bad as threads are forced to synchronize to return a cached class from elsewhere whereas the cached value return could all happen concurrently.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


More information about the jboss-jira mailing list