我们是否需要使用MappedByteBuffer.force()将数据刷新到磁盘?

jan*_*ith 12 java performance nio synchronized blocking

我正在使用MappedByteBuffer来加速文件读/写操作().我的问题如下:

  1. 我不确定是否需要使用.force()方法将内容刷新到磁盘.似乎没有.force(),.getInt()仍然可以完美地工作(好吧,因为这是一个内存映射缓冲区,我假设.getInt()从磁盘中获取数据,这意味着数据已被刷新到磁盘已经.

  2. .force()方法是阻塞方法吗?

  3. 阻塞方法是同步块吗?

  4. 无论是否调用.force()方法,都会有巨大的性能差异.手动调用.force()有什么好处?我们应该在哪种情况下使用它?我假设没有调用它,数据仍将被写入场景后面的磁盘.

  5. 如果我们需要调用.force(),从另一个线程调用它有助于提高性能吗?由于同步问题,它会破坏数据吗?

    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;

公共类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");
}
Run Code Online (Sandbox Code Playgroud)

}

use*_*421 5

  1. 仅当您有极端的事务需求(即您正在实现数据库)时才应调用它。getInt() 从内存中读取:操作系统将文件分页进出该内存。

  2. 没有具体说明。

  3. 如果指定的话,方法将被同步。这与他们是否阻止无关。

  4. 参见(1)。数据仍将被写入,但取决于操作系统的意愿,而不是您的意愿。

  5. 我对此表示怀疑,但请参阅 (2),并且我怀疑您根本不需要调用它,请参阅 (1)。


Yao*_*Yao 5

MappedByteBuffer.force()在Windows中并非没有用。我使用了http://technet.microsoft.com/zh-cn/sysinternals/bb896645的 “进程监视器”工具来监视文件访问。根据日志记录,MappedByteBuffer.force()将立即以非缓存同步模式调用Windows API WriteFile()。可靠性应类似于FileChannel.force(),后者将立即调用Windows API FlushFileBuffers()来写入文件。因此,MappedByteBuffer.force()对于大多数用法来说足够可靠。使用Java 1.6.0_24在Windows 7 64位上进行了测试。