Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8057655

Empty delegating URLClassLoader performance is erratic

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Duplicate
    • Icon: P3 P3
    • 10
    • 9
    • hotspot

      This seems to be the known issue, but I haven't found any quantifiable measures of it. It does affect classloader benchmarks in a profound ways.

      In short, if we write a very short classloader torture benchmark, which always delegates the actual classloading to a system classloader:
      (full code and executable JAR is here: http://cr.openjdk.java.net/~shade/8057655/classload-torture.zip)

          @Benchmark
          public Class<?> load() throws ClassNotFoundException {
              URLClassLoader loader = new URLClassLoader(new URL[0]);
              return Class.forName("java.util.HashMap", true, loader);
          }

      ...then we will observe a pathological behavior: the steady state performance is erratic. See e.g. out-of-box 8u40:
       http://cr.openjdk.java.net/~shade/8057655/8u40-oob.log

      Now, it is admittedly because we overload VM Dictionary much, and clean it up on full GCs. We can see that by increasing the heap size, pushing the full GC farther away:
       http://cr.openjdk.java.net/~shade/8057655/8u40-1g.log
       http://cr.openjdk.java.net/~shade/8057655/8u40-4g.log

      Notice how we gradually degrade, then recover after GC, then start degrading again. To further illustrate that, this is the run with GC forced after each iteration:
       http://cr.openjdk.java.net/~shade/8057655/8u40-4g-forcegc.log

      That means we are running tens of times slower without a cleanup. Profiling 8u40-4g case yields the expected bottleneck:
       http://cr.openjdk.java.net/~shade/8057655/output.txt

      We are spending >80% doing Dictionary::find().

      N.B.: Increasing both StringTableSize and SymbolTable size to 1000001 does not help to mitigate this:
       http://cr.openjdk.java.net/~shade/8057655/8u40-4g-1000001.log

      Avoiding this issue can go two routes:
        1) Doing more aggressive dictionary cleanup: arguably hard, since we need to identify dead classloaders, and unload classes first -- can we really do that without full GC?
        2) Making Dictionary more resilient to overload: it does not seem to be connected with a dynamic resizing proposal

            coleenp Coleen Phillimore
            shade Aleksey Shipilev
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: