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

2022-09-04 21:48:41

我正在使用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;

公共类主 {

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");
}

}


答案 1

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


答案 2
  1. 只有当您有极端的事务性要求(即您正在实现数据库)时,才应调用它。getInt() 从内存中读取:操作系统将文件分页到该内存中或从该内存中取出。

  2. 未指定。

  3. 如果指定了方法,则会同步方法。这与他们是否阻止无关。

  4. 见(1)。数据仍将写入,但由操作系统的心血来潮而不是您的。

  5. 我对此表示怀疑,但请看(2),我怀疑你是否需要称呼它,见(1)。


推荐