Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8205162

FileChannel force(false) is slow on macOS

XMLWordPrintable

    • x86_64
    • os_x

      ADDITIONAL SYSTEM INFORMATION :
      MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports).

      java version "10.0.1" 2018-04-17
      Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
      Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)

      java version "1.8.0_171"
      Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
      Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)


      A DESCRIPTION OF THE PROBLEM :
      On Mac, repeated use of randomAccessFile.getChannel().force(false) is almost 100 times slower using Java 10 than using Java 8. On Linux, the speed is reasonably fast and similar in both versions.

      We encountered this in the wild in an application which uses Berkeley DB JE. The application is suddenly dramatically slower on Mac with Java 9 and Java 10.


      REGRESSION : Last worked in version 8u171

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile the class ForceTimer given below for Java 8.

      $ JAVA_HOME=`/usr/libexec/java_home -v 1.8` java ForceTimer
      Elapsed time 554ms

      $ JAVA_HOME=`/usr/libexec/java_home -v 10` java ForceTimer
      Elapsed time 42443ms

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expected the run time of this program to be similar in Java 8 and Java 10.
      ACTUAL -
      Running the program in Java 10 is much slower than running in Java 8.

      ---------- BEGIN SOURCE ----------
      import java.io.*;

      public class ForceTimer {
          public static void main(String[] args) throws Exception {
              File tempFile = File.createTempFile("tmp", null);
              RandomAccessFile randomAccessFile = new RandomAccessFile(tempFile, "rw");
              long start = System.currentTimeMillis();
              for (int i = 0; i < 10000; i++) {
                  String line = i + "\n";
                  randomAccessFile.write(line.getBytes());
                  randomAccessFile.getChannel().force(false);
              }
              long end = System.currentTimeMillis();
              System.out.println("Elapsed time " + (end - start) + "ms");
              randomAccessFile.close();
              tempFile.delete();
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use Java 8 on Mac, or Java 10 on Linux.

      FREQUENCY : always


            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: