JDK-7129164 : JNI Get/ReleasePrimitiveArrayCritical don't scale
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: hs23
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2012-01-11
  • Updated: 2012-03-22
  • Resolved: 2012-02-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 Other
7u4Fixed 8Fixed hs23Fixed
Related Reports
Relates :  
JNI critical methods in Hotspot (such as GetPrimitiveArrayCritical, ReleasePrimitvieArrayCritical and so on) contain Atomic methods (inc, dec)
to update shared variable _jni_lock_count. In case of frequent calls to these
methods we observe true sharing problem. The attached draft patch skips
grabbing the jni lock (and thus updating _jni_lock_count) unless a gc is
needed and the thread isn't already in a critical section.

See the preliminary results for a simple micro benchmarks in attach that check
scalability on WSM EP (RHEL 5.5, V7B147):

Threads                       1         12       24

Default hotspot             7244       9504    17540

Patched hotspot             7408      81780    93819

Patched / Default           1.02       8.61     5.25

EVALUATION http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/1a2723f7ad8e

EVALUATION 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale Summary: Reviewed-by: The machinery for GC_locker which supports GetPrimitiveArrayCritical maintains a count of the number of threads that currently have raw pointers exposed. This is used to allow existing critical sections to drain before creating new ones so that a GC can occur. Currently these counts are updated using atomic all the time, even if a GC isn't being requested. This creates scalability problem when a lot of threads are hammering atomic operations on the jni_lock_count. The count only needs to be valid when checking if a critical section is currently active and when draining the existing sections. The fix is to make the count be computed as part of the safepointing machinery and to only decrement the counters when _needs_gc is true. In debug mode the old count is maintained and validated against the lazily computed count. On a microbenchmark that stresses GetPrimitiveArrayCritical with many threads and relatively short critical section it can more than double the throughput. This also slightly speeds up the normal GetPrimtiveArrayCritical calls. Mostly it's not easily measurable with larger scale programs. Tested with microbenchmark that stresses GetPrimtiveArrayCritical and the crypto benchmarks of specjvm2008 on x86 and sparc. I also ran the java.io regression tests from the JDK.

EVALUATION http://hg.openjdk.java.net/hsx/hotspot-comp/hotspot/rev/1a2723f7ad8e