4

それぞれのサイズが約 6 GB の複数のファイル (サーバーからの大きなログファイル) を処理するプログラムを作成しています。しかし、プログラムを異なるスレッドに分割できないため、CPU の 25% しか使用していません (使用可能な 4 つのうち 1 つの CPU スレッド)。作業は順番に実行する必要があります。

クアッドコアのCPUを持っているので、同時に4ファイルまで処理しようと考えていましたが、HDDのランダムディスクアクセス性能に限界があります。

しかし、数日後には、SSD と 8 GB の RAM を搭載したラップトップを使用することになります。たとえば、メモリ内の各ファイルの最初の 1 GB をマップし、それらを 4 つの異なるスレッドで処理することは可能でしょうか? そして、マップされたファイルの最後に到達したら、メモリ内のファイルの次の 1 GB をマップして続行できるはずです。1 GB をメモリにマッピングすることは、SSD では約 400 MB/秒の読み取り速度になるため、問題にはならないはずです。

これは FileChannel を使用して実行できることはわかっていますが、ファイルの一部のみをマッピングすることについてはわかりません。

ありがとう、シーベ

4

3 に答える 3

1

ファイルをメモリ マップすると、ファイルは実際にはメモリに転送されません (メモリ マッピングとは逆になります)。

代わりに、カーネルが特別に扱うメモリアドレスが与えられます。アクセスすると、カーネルはメモリのページにファイルの内容をロードします。その後、OS が一部のメモリを再利用することを決定すると、ページはアンロードされます。マップされたファイルは拡張スワップ スペースと考えることができます。

つまり、十分なメモリ アドレスがある場合 (つまり、64 ビット OS と JVM がある場合)、システム メモリよりも大きなファイルをマップできます。

于 2012-08-29T13:09:20.350 に答える
0

FileChannel を使用して、メモリ内のファイル全体を一度にマップできます。ただし、データをシーケンシャルに読み取り、処理が自明でない場合は、各スレッドでプレーンな FileInputStream を使用する方がはるかに簡単に使用でき、ほぼ同じパフォーマンスが得られます。

于 2012-08-29T12:33:14.547 に答える
0

FileChannel から取得できる MemoryMappedByteBuffer を使用したい。これも参照してください: Javaのメモリマップファイルとこれ: http://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html

また、Peter が指摘したように、処理が CPU を集中的に使用しない場合、最初に処理する前にファイルをメモリに移動してもあまり効果がない可能性があります。一発でやったほうがいいかもしれません。ご存じのとおり、メモリへのコピーは無料ではありません。

于 2012-08-29T12:39:30.263 に答える