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

RandomAccessFile synchronous write mode ignored on JDK1.4 on Windows

    Details

    • Subcomponent:
    • Resolved In Build:
      mantis
    • CPU:
      x86
    • OS:
      windows_xp
    • Verification:
      Verified

      Description



      Name: wm7046 Date: 07/08/2002


      FULL PRODUCT VERSION :
      Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)

      FULL OPERATING SYSTEM VERSION : Any Windows, but tested
      only on XP


      A DESCRIPTION OF THE PROBLEM :
      The 1.4 JDK introduces a new "synchronous write" mode flags
      that can be specified in the java.io.RandomAccessFile
      constructor. This essentially is intended to open the file
      in the equivalent of Solaris' "O_SYNC" and "O_DSYNC" modes.
      These flags are apparently totally ignored on Windows XP,
      and likely all other versions of Windows.

      Please give this bug a high priority as there is no
      easy or similarly performing work-around. Also, this is a
      "silent" bug, it is not detectable except by those that know
      what the performance characteristics should be. Also, this
      but is a "very bad thing" for data integrity.


      ------------------------------------------------------------

      THE FIX:

      The Sun JDK apparently uses the Windows POSIX library for
      file I/O. Unfortunately, this library doesn't support
      synchronous writes (i.e. O_SYNC or O_DSYNC), but I'm not
      100% sure on this. A fix may require use of the non-POSIX
      Win32 "CreateFile" function to open the file with the Win32
      flag "FILE_FLAG_WRITE_THROUGH".

      At BEA I have written native code that does just this, it
      was this work that led me to the JDK1.4 bug...
       


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run provided sample code on java 1.4 on Windows:
          "java TooFast"

      Note that on Windows, unlike Solaris, the on-hard-drive
      write-cache is enabled even for synchronous writes, unlike
      Solaris. The test failure above may require disabling this
      cache to recreate, to do this:
        control panel
        administrative tools
        computer management
        device manager
        disk drives
        click on your hard-drive
        policies tab
        uncheck "enable write caching on disk"


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      On my Windows XP laptop 5400 RPM IDE hard-drive, the result
      was:
      <src_jms fileio/test> java TooFast

      83333.24723782427 synchronous-writes/sec

      Exception in thread "main" java.io.IOException: WAY WAY WAY
      TOO FAST,
          more than 5000 sync writes/sec,
          Expect lower than 1000 writes per second
           - (usually much lower).
              at TooFast.main(TooFast.java:29)

      REPRODUCIBILITY :
      This bug can be reproduced always.

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

      /**
       * Show something is wrong with JDK1.4 synchronous writes on Windows.
       */

      public class TooFast {
        public static void main(String [] args) throws Exception {
          int NUMWRITES = 5000;
          RandomAccessFile f;
          Random r = new Random();

          File file = new File("TooFast.out");
          if (file.exists()) file.delete();
          f = new RandomAccessFile(file,"rwd");

          double before = (double)System.currentTimeMillis()/1000.0;
          for (int i = NUMWRITES; i > 0; i--) {
            f.seek(r.nextInt(100000));
            f.write(new byte[1000]);
          }
          double after = (double)System.currentTimeMillis()/1000.0;

          double writesPerSec = (NUMWRITES / (after - before));
          System.out.println("\n" + writesPerSec + " synchronous-writes/sec\n");

          if (writesPerSec > 5000)
            throw new IOException("WAY WAY WAY TOO FAST,\n "
                     + " more than 5000 sync writes/sec,\n "
                     + " Expect lower than 1000 writes per second\n "
                     + " - (usually much lower).");

          System.out.println();
        }
      }



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

      CUSTOMER WORKAROUND :
      Modify application to call fd.sync() after each write() - a
      huge performance hit. Alternatively, write your own native
      code, which BEA has already done.
      (Review ID: 158582)
      ======================================================================

        Attachments

          Activity

            People

            • Assignee:
              mmcclosksunw Michael Mccloskey (Inactive)
              Reporter:
              mmma Marvin Ma (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Imported:
                Indexed: