Uploaded image for project: 'OpenJDK'
  1. OpenJDK
  2. OPENJDK-3030

jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent has race condition allowing for CPU spikes

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • 11.0.22 GA, 17.0.13 GA
    • None
    • None
    • False
    • Hide

      None

      Show
      None
    • False
    • Low

      AbstractClassLoaderValue.computeIfAbsent has a race condition that can result in high CPU busy spins if the concurrent threads share a created Memoizer that throws an exception.

      If multiple threads hit AbstractClassLoaderValue.computeIfAbsent, at once they all see a null Memoizer at first and all create their own. That's then overhead for no reason then as they fallback to using the first created Memoizer stored on the map here. So then all threads are blocking to use the same Memoizer. If that first Memoizer off the map returns an exception, this is where CPU load can get quite problematic. For a thread fetching the Memoizer off the map, it silently catches the exception from the Memoizer and tries again. The exception throwing Memoizer will stay on the map until the original thread that put it attempts it and catches the exception to remove it here. So then the race can play out like below for high CPU spins in possibly many threads:
      1. Thread 1 creates a Memoizer that's going to throw an exception and puts it on the map
      2. Thread 2-N fetch the Memoizer off the map and attempt here
      3. Thread 2-N silently catch the exception here and rerun the loop to hit the same calls so long as this Memoizer stays on the map
      4. Sometime later, Thread 1 is scheduled and gets to progress. It finally catches the exception and removes the Memoizer here to end the CPU spins in other threads that may be attempting that Memoizer.

      In my tests, I've seen been able to see with some additional debugging individual AbstractClassLoaderValue.computeIfAbsent calls reaching up to 1800+ busy iterations and then confirmed the high CPU state is avoided if a map.remove is added here.

            mtorre@redhat.com Mario Torre
            rhn-support-aogburn Aaron Ogburn
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: