GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream

Martin Buchholz martinrb at google.com
Wed Mar 7 02:44:47 UTC 2018


Thanks Ian and Sherman for the excellent presentation and memories of
ancient efforts.

Yes, Sherman, I still have vague memory that attempts to touch any
implementation detail in this area was asking for trouble and someone would
complain.  I was happy to let you deal with those problems!

There's a continual struggle in the industry to enable more checking at
test time, and -Xcheck:jni does look like it should be possible to
routinely turn on for running all tests.  (Google tests run with a time
limit, and so any low-level performance regression immediately causes test
failures, for better or worse)

Our problem reduces to accessing a primitive array slice from native code.
The only way to get O(1) access is via GetPrimitiveArrayCritical, BUT when
it fails you have to pay for a copy of the entire array.  An obvious
solution is to introduce a slice variant GetPrimitiveArrayRegionCritical
that would only degrade to a copy of the slice.  Offhand that seems
relatively easy to implement though we would hold our noses at adding yet
more *Critical* functions to the JNI spec.  In spirit though it's a
straightforward generalization.

Implementing Deflater in pure Java seems very reasonable and we've had good
success with "nearby" code, but we likely cannot reuse the GNU Classpath
code.

Thanks for pointing out
JDK-6311046: -Xcheck:jni should support checking of
GetPrimitiveArrayCritical
which went into jdk8 in u40.

We can probably be smarter about choosing a better buffer size, e.g. in
ZipOutputStream.

Here's an idea:  In code like this
  try (DeflaterOutputStream dout = new DeflaterOutputStream(deflated)) {
     dout.write(inflated, 0, inflated.length);
   }
when the DeflaterOutputStream is given an input that is clearly too large
for the current buffer size, reorganize internals dynamically to use a much
bigger buffer size.

It's possible (but hard work!) to adjust algorithms based on whether
critical array access is available.  It would be nice if we could get the
JVM to tell us (but it might depend, e.g. on the size of the array).


More information about the core-libs-dev mailing list