Uploaded image for project: 'Tapestry 5'
  1. Tapestry 5
  2. TAP5-2336

Lock contention in AssetSourceImp

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Major
    • Resolution: Fixed
    • None
    • 5.4
    • None

    Description

      While benchmarking tapestry framework with concurency level = 4 I found lock contention in AssetSourceImpl.java.

      Lock looks as follows:

      java.lang.Thread.State: BLOCKED (on object monitor)
      at java.util.zip.ZipFile.getEntry(ZipFile.java:304)

      • locked <0x0000000711ee6800> (a java.util.jar.JarFile)
        at java.util.jar.JarFile.getEntry(JarFile.java:226)
        at java.util.jar.JarFile.getJarEntry(JarFile.java:209)
        at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:840)
        at sun.misc.URLClassPath$JarLoader.findResource(URLClassPath.java:818)
        at sun.misc.URLClassPath.findResource(URLClassPath.java:176)
        at java.net.URLClassLoader$2.run(URLClassLoader.java:551)
        at java.net.URLClassLoader$2.run(URLClassLoader.java:549)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findResource(URLClassLoader.java:548)
        at java.lang.ClassLoader.getResource(ClassLoader.java:1139)
        at java.lang.ClassLoader.getResource(ClassLoader.java:1134)
        at org.apache.catalina.loader.WebappClassLoader.getResource(WebappClassLoader.java:1417)
        at org.apache.tapestry5.ioc.internal.util.ClasspathResource.resolveURL(ClasspathResource.java:79)
        at org.apache.tapestry5.ioc.internal.util.ClasspathResource.toURL(ClasspathResource.java:61)
        at org.apache.tapestry5.ioc.internal.util.AbstractResource.computeExists(AbstractResource.java:236)
        at org.apache.tapestry5.ioc.internal.util.AbstractResource.exists(AbstractResource.java:218)
        at org.apache.tapestry5.ioc.internal.util.AbstractResource.findLocalizedResource(AbstractResource.java:177)
        at org.apache.tapestry5.ioc.internal.util.AbstractResource.populateLocalizationCache(AbstractResource.java:159)
        at org.apache.tapestry5.ioc.internal.util.AbstractResource.forLocale(AbstractResource.java:136)
        at org.apache.tapestry5.internal.services.AssetSourceImpl.getLocalizedAssetFromResource(AssetSourceImpl.java:134)
        at org.apache.tapestry5.internal.services.AssetSourceImpl.getAssetInLocale(AssetSourceImpl.java:107)
        at org.apache.tapestry5.internal.services.AssetSourceImpl.getAsset(AssetSourceImpl.java:87)
        at $AssetSource_369c373aab0b9a.getAsset(Unknown Source)
        at org.apache.tapestry5.internal.services.javascript.CoreJavaScriptStack.getJavaScriptLibraries(CoreJavaScriptStack.java:154)

      Here is a cache to prevent lock contention, but I'm not sure whether it works properly.

      AssetSourceImpl.java
      private final Map<Resource, SoftReference<Asset>> cache = new WeakHashMap<Resource, SoftReference<Asset>>();
      

      Here the problem is that Resource is used as a key.
      So the cache entry will be removed as soon as key is available for garbage collection.
      Resources aren't always long-lived objects.
      For example resources produced by AssetSourceImpl.findResource(Resource baseResource, String path) has a very short lifecycle.

      It would be good to use SoftHashMap instead of WeakHashMap here, but it is not included in standard Java.

      To check my assumption I created cache based on ConcurrentHashMap instead of WeakHashMap. As result of it lock contention disappeared and overall performance increased.

      Attachments

        Activity

          People

            hlship Howard Lewis Ship
            mihasik Michael Mikhulya
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: