13

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

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

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

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

  4. 调用或不调用 .force() 方法存在巨大的性能差异。手动调用 .force() 有什么好处?我们应该在什么情况下使用它?我假设不调用它,数据仍将在后台写入磁盘。

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

    导入 java.io.FileNotFoundException;导入 java.io.IOException;导入 java.io.RandomAccessFile;导入 java.nio.MappedByteBuffer;导入 java.nio.channels.FileChannel;导入 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");
}

}

4

4 回答 4

5

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

于 2011-07-08T02:34:04.190 回答
4
  1. 只有当您有极端的事务要求时才应该调用它,即您正在实现一个数据库。getInt() 从内存中读取:操作系统将文件分页进出该内存。

  2. 未指定。

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

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

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

于 2010-11-04T13:09:07.533 回答
2

好的,对我的回答持保留态度(我不是 NIO 专家)

1.)putInt(i, i)将写入内存中的 MappedByteBuffer (mbb),并且操作系统会在需要test.map时将该值传输到实际的底层文件 ()。

Usingforce()告诉操作系统“现在”传输数据(如果您有另一个需要从该文件读取的进程,这可能很有用)。

getInt(i)正在从 MappedByteBuffer (mbb) 中读取值,如果您force()按照自己的方式使用,那么您知道您的文件在后台与该内存缓冲区同步)。

您可能不需要使用force()

2.) 不确定,我认为Java 7 NIO.2 开始暗示能够以非阻塞方式执行此类操作。我现在还在研究这个。

3.) 这是两个不同的问题。我建议看看 Doug Lea 的书 :-)。

4.) 如 1.) 所述,force() 将告诉操作系统写入“现在”,否则操作系统会在感觉需要时写入。

于 2010-11-04T13:36:33.610 回答
1

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

force() 在 Windows 上没用。相当可怕的虫子。

于 2010-12-28T21:55:41.000 回答