Do we need to use MappedByteBuffer.force() to flus

2019-04-21 05:56发布

I am using MappedByteBuffer to speed up file read/write operations(). My questions as below:

  1. I am not sure if I need to use .force() method to flush the content to disk or not. It seems like without .force(), the .getInt() can still work perfectly (well, since this is a memory-mapped buffer, i assume .getInt() fetches the data from disk, which means the data has been flushed into disk already.

  2. Is the .force() method a blocking method?

  3. Is a blocking method a synchronized block?

  4. There is a huge performance difference with or without calling .force() method. What's the benefit of calling .force() manually? Under which situation should we use it? I assume without calling it, the data will still be written to disk behind the scene.

  5. If we needs to call .force(), will calling it from another thread helps to improve performace? Will it corrupt the data because of synchronization problem?

    import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode;

public class Main {

public static void main(String[] args) throws IOException {
    System.out.println("start");

    RandomAccessFile raf = new RandomAccessFile("test.map", "rw");
    FileChannel fc = raf.getChannel();
    MappedByteBuffer mbb = fc.map(MapMode.READ_WRITE, 0, 2000000);

    int total = 0;
    long startTime = System.currentTimeMillis();
    for (int i = 0; i < 2000000; i += 4) {
        mbb.putInt(i, i);
        //mbb.force();
        total += mbb.getInt(i);
    }
    long stopTime = System.currentTimeMillis();

    System.out.println(total);
    System.out.println(stopTime - startTime);
    System.out.println("stop");
}

}

4条回答
够拽才男人
2楼-- · 2019-04-21 06:38

OK, take my answer with a grain of salt (I'm not a NIO expert)

1.) The putInt(i, i) will write to the MappedByteBuffer (mbb) which is in memory and the Operating System transfers that value into the actual underlying file (test.map) when it wants to.

Using force() tells the Operating System to transfer the data 'now' (which can be useful if you've got another process which needs to read from that file).

Your getInt(i) is reading the value from the MappedByteBuffer (mbb), if you use force() in the way that you are then you know that under the hood your file is in sync with that memory buffer).

Chances are you don't need to use force()

2.) Not sure, I think it is as the Java 7 NIO.2 stuff starts to allude to being able to do this sort of thing in a non-blocking manner. I'm still researching that at the moment.

3.) These are two separate concerns. I'd recommend having a look at Doug Lea's book :-).

4.) As 1.) states, force() will tell the OS to write 'now', else the OS writes when it feels like it.

查看更多
smile是对你的礼貌
3楼-- · 2019-04-21 06:41

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6816049

force() is useless on Windows. Pretty scary bug.

查看更多
神经病院院长
4楼-- · 2019-04-21 06:51
  1. You should call it only if you have extreme transactional requirements, i.e. you are implementing a database. getInt() reads from memory: the operating system pages the file into and out of that memory.

  2. It is not specified.

  3. Methods are synchronized if so specified. It has nothing to do with whether they block or not.

  4. See (1). Data will still be written but at the operating system's whim rather than yours.

  5. I doubt it, but see (2), and I doubt that you need to call it at all, see (1).

查看更多
三岁会撩人
5楼-- · 2019-04-21 07:00

MappedByteBuffer.force() is not useless in Windows. I used "Process Monitor" tool from http://technet.microsoft.com/en-us/sysinternals/bb896645 to monitor the file access. According to the logging, MappedByteBuffer.force() will immediately call Windows API WriteFile() in Non-cached Synchronous mode. The reliability should be similar as FileChannel.force() which will call Windows API FlushFileBuffers() immediately to write file. Therefore, MappedByteBuffer.force() is reliable enough for most kinds of usages. Tested on Windows 7 64bit with Java 1.6.0_24.

查看更多
登录 后发表回答