2

我正在尝试在 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 是否需要一些时间。过了一会儿,操作系统实际上必须开始将字节写入文件。但是,在这里,该过程实际上使整个操作系统处于饥饿状态。我怎样才能避免这种情况?

4

1 回答 1

2

您正在映射 512x128x1024x1024 字节或 64 GB,而您有 8 GB。所以你实际上是过度使用了 8 倍的内存。这对于阅读来说是可以的,因为操作系统可以将你的页面错误到一个充满空值的页面,所有这些页面甚至可能是同一个页面。但是当你写的时候,页面必须虚拟存在。所以你在折腾。您需要 8 倍的主内存或小于 1/8 的映射字节缓冲区数量。

于 2012-09-25T01:11:58.197 回答