我正在尝试在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是否需要一些时间。过了一会儿,操作系统实际上必须开始将字节写入文件中。但是,在这里,这个过程基本上使整个操作系统挨饿。我怎么能避免这个?
答案 0 :(得分:2)
您正在映射512x128x1024x1024字节或64千兆字节,并且您有8千兆字节。所以你实际上是将内存提交了8倍。这对于读取是可以的,因为操作系统只能将你的页面错误归结为一个充满空值的页面,所有这些页面甚至可以是同一页面。但是当你写作时,页面必须被带入虚拟存在。所以你正在挣扎。你需要8倍的主存储器或者&lt; 1/8量的映射字节缓冲区。