在READ_WRITE模式下使用大量MappedByteBuffer可以减慢Windows 7的速度

时间:2012-09-24 20:08:45

标签: java windows-7 memory-mapped-files

我正在尝试在READ_WRITE模式下使用Java MappedByteBuffers来映射大文件(数十GB)或一组许多小文件(~128MB)。这是为了实现高性能的B树。

我的问题是,在我的带有8GB RAM和JDK 7的Windows 7笔记本电脑上,一切正常,直到物理内存已满且操作系统开始实际将数据写入文件。此时,Windows会慢慢爬行。 I / O似乎完全饿死任何其他活动。鼠标指针几乎无法移动,我通常最终不得不强行重启机器。

以下代码演示了此问题:

public static void testMap() throws Exception
{
    MappedByteBuffer[] mbbs = new MappedByteBuffer[512];
    for (int i = 0; i < 512; i++)
    {
        System.out.printf("i=%d%n", i);
        RandomAccessFile raf = new RandomAccessFile(String.format("D:/testMap.%d.bin", i), "rw");
        mbbs[i] = raf.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 128*1024*1024);
        for (int j = 0; j < 128*1024; j++) {
            mbbs[i].put(j*1024, (byte)(i*j));
        }
    }
}

我不介意I / O是否需要一些时间。过了一会儿,操作系统实际上必须开始将字节写入文件中。但是,在这里,这个过程基本上使整个操作系统挨饿。我怎么能避免这个?

1 个答案:

答案 0 :(得分:2)

您正在映射512x128x1024x1024字节或64千兆字节,并且您有8千兆字节。所以你实际上是将内存提交了8倍。这对于读取是可以的,因为操作系统只能将你的页面错误归结为一个充满空值的页面,所有这些页面甚至可以是同一页面。但是当你写作时,页面必须被带入虚拟存在。所以你正在挣扎。你需要8倍的主存储器或者&lt; 1/8量的映射字节缓冲区。