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

Xueming Shen xueming.shen at oracle.com
Mon Mar 5 20:45:56 UTC 2018


On 3/5/18, 11:15 AM, Ian Rogers wrote:
> Thanks! Changing the DeflaterOutputStream buffer size to be something 
> other than the default reduces the number of JNI native calls and is a 
> possible work around here, as this is an implementation detail could 
> it be made in the JDK? Unfortunately larger input sizes will also 
> regress the issue as the number of calls is "input size / buffer 
> size". The JNI critical may give direct access to the array but 
> depending on the GC, may require a lock and so lock contention may be 
> a significant issue with the code and contribute to tail latencies. In 
> my original post I mention this is difficult to measure and I think 
> good practice is to avoid JNI critical regions.

We do have a history on the usage of 
GetPrimitiveArrayCritical/Elements() here regarding the
potential "lock contention", copy overhead... and went back and forth on 
which jni call is the
appropriate one to go. Martin might still have the memory of that :-)

Some related bugids:

https://bugs.openjdk.java.net/browse/JDK-6206933
https://bugs.openjdk.java.net/browse/JDK-6348045
https://bugs.openjdk.java.net/browse/JDK-5043044
https://bugs.openjdk.java.net/browse/JDK-6356456

There was once a "lock contention" bug that affects the performance of 
GetPrimitiveArrayCritical.
But that bug was fixed since (in hotspot). With various use scenario, a 
"copy overhead" when using
GetPrimitiveArrayElement() was concluded not acceptable, at least back then.

It appears to be an easy to do/must to do (nice to have?) to increase 
the "default buf size" used in
DeflaterOutputStream. But every time we tried to touch those default 
setting/configuration values
that have been there for decades, some "regression" complains would come 
back and hurt us :-)
For this particular case a potential "regression" is that the footprint 
increase because of the
the default buffer size is increased from 512 -> xxxx might not be 
desirable for some use
scenario. For example if hundreds of thousands of DeflaterOutputStream 
are being open/closed
on hundreds of thousands of compressed jar or zip files the increase 
might be huge. And the API
does provide the constructor that you can customize the buffer size. It 
might be desired to keep
the default size asis. That said, I agreed that 512 appears to be a 
"too-small" default size if the
majority of the use scenario for the DeflaterOutputStream is to open a 
jar/zip file entry.

Sherman






More information about the hotspot-dev mailing list