RFR: JDK-8142508: To bring j.u.z.ZipFile's native implementation to Java to remove the expensive jni cost and mmap crash risk

Xueming Shen xueming.shen at oracle.com
Wed Nov 11 20:22:00 UTC 2015


Please help review the changes for JDK-8142508 (third try)

Issue: https://bugs.openjdk.java.net/browse/JDK-8142508
webrev: http://cr.openjdk.java.net/~sherman/8142508/webrev

Mainly to address the issues in current j.u.z.ZipFile implementation as listed

(1) The ZIP file format support code is in native C (shared with the VM via
      ZipFile.c -> zip_util.c). Any entry lookup, creation operation requires multiple
      round-trips of expensive jni calls.

(2) The native C implementation which uses mmap to map in the central directory
      table appears to be a big risk of vm crash when the underlying jar file gets
      overwritten with new contents while it is still being used by other ZipFile. The
      crash reports keep coming in even after we have introduced in system flag
      to disable it (sun.zip.disableMemoryMapping).

(3) The use of "filename + lastModified()" cache (zip_util.c) appears to be broken
      if the timestamp is in low resolution/precision (File.getModified() for example,
      might only have "second" ersolution on solaris/linux), and/or the file is being

The clean solution appears to bring the ZIP format support code completely from
native to Java to remove the jni invocation cost and the mmap risk. Also to use
the fileKey and lastModified from java.nio.file.attribute.BasicFileAttributes to have
better/correct cache matching.


This simple jmh measurement suggests a big boost of the performance of
ZipFile.getEntry()/entries()/getStream() which are basically entry related
accesses (the "open only" has some regression, which is expected as we
switched from the mmap to simply read the cen table in into a byte[])


# JDK9 base

Benchmark                  Mode  Cnt    Score    Error  Units
MyBenchmark.testEntries    avgt   50   13.671 ±  0.385  ms/op
MyBenchmark.testGetEntry   avgt   50   17.414 ±  0.803  ms/op
MyBenchmark.testGetStream  avgt   50   42.398 ± 10.136  ms/op
MyBenchmark.testOpen       avgt   50    3.049 ±  0.094  ms/op
MyBenchmark.testRead       avgt   50  215.179 ±  9.926  ms/op
MyBenchmark.testReadAll    avgt   50  244.422 ± 19.375  ms/op
# JDK9 ZipFile without jni invocation

Benchmark                  Mode  Cnt    Score    Error  Units
MyBenchmark.testEntries    avgt   50    6.436 ±  0.422  ms/op
MyBenchmark.testGetEntry   avgt   50   10.021 ±  0.699  ms/op
MyBenchmark.testGetStream  avgt   50   38.713 ± 16.687  ms/op
MyBenchmark.testOpen       avgt   50    3.288 ±  0.119  ms/op
MyBenchmark.testRead       avgt   50  220.653 ±  8.529  ms/op
MyBenchmark.testReadAll    avgt   50  249.798 ± 18.438  ms/op


Verified the new ZipFile runs as expected when the underlying jar/zip file get
deleted/overwritten when the zip still be used. The "old" ZipFile fails to continue
to work but no crash, and the "new" one works correctly on updated zip file
without problem (The test runs a little long, have not decided if it should be
checked in as unit test).


More information about the core-libs-dev mailing list