2

Java MappedByteBuffers を READ_WRITE モードで使用して、大きなファイル (数十 GB) または多数の小さなファイルのセット (~128MB) をマップしようとしています。これは、高パフォーマンスの B ツリーを実装するためです。

私の問題は、8 GB の RAM と JDK 7 を搭載した Windows 7 ラップトップでは、物理メモリがいっぱいになり、OS が実際にファイルへのデータの書き込みを開始するまで、すべてがうまくいくことです。この時点で、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 に時間がかかってもかまいません。しばらくすると、OS は実際にファイルへのバイトの書き込みを開始する必要があります。しかし、ここでは、プロセスは基本的に OS 全体を枯渇させます。どうすればこれを回避できますか?

4

1 に答える 1

2

512x128x1024x1024 バイト、つまり 64 ギガバイトをマッピングしており、8 ギガバイトあります。したがって、文字通りメモリを 8 倍オーバーコミットしています。OS は null でいっぱいのページにページ フォールトすることができ、それらのページはすべて同じページである可能性があるため、読み取りには問題ありません。しかし、あなたが書くとき、ページは仮想的な存在に持ち込まれなければなりません。だからあなたはスラッシングしています。メイン メモリの 8 倍、またはマップされたバイト バッファの量の 1/8 未満のいずれかが必要です。

于 2012-09-25T01:11:58.197 に答える