1

編集:

ファイルをメモリにロードする(必要に応じて場所を更新する)代わりに、興味のある場所へのインデックスのみを保持する FileInputStream を使用することになりました。

これは、毎回保持するデータが少ない場合は使用するメモリを少なくする (メモリ アクセスを増やす) ように構成でき、保持するデータが多い場合はメモリを増やす (メモリ アクセスを少なくする) ように構成できます。

コードをループしていると仮定して、応答時間を使用してバッファを調整できます。

これは、ノンブロッキング I\O を使用して改善できると確信していますが、直感的ではなく、簡単に制御できる単純なものを使用することにしました。


大きなファイルのバイト シーケンスを比較する大学向けのプロジェクトがあります。

これを迅速に行うために、すべてのファイルをメモリにロードし (ファイルは合計で約 500 MB です)、小さなデータベースに抽出する際に情報を保存しながらそれらを比較することにしました (クエリはあまり行われません)。

「File」クラスを新しいクラス「MappedFile」に拡張しました。各 Mappedfile には、ファイルのバイトを保持するバイト配列 (構築時に作成される) があります。

これは MemFile クラス全体です。

public class MemFile extends File{

private String md5;
private byte[] bytes;

public MemFile(String pathname) {
    super(pathname);
}

public byte[] getBytes(){
    if (this.bytes == null){
        this.bytes = FileUtils.getFileBytes(this);
    }
    return this.bytes;
}

public String getMD5(){
    if (this.md5 == null){
        this.md5 = MD5Generator.generate(this.getAbsolutePath());
    }
    return this.md5;
    }
}

それらのリストを保持していて、大きなバイト配列から小さな配列を抽出してから、他のファイルでそれらを探します。

私の問題は、500 MB のファイルの小さなサブセットのみを使用すると、メモリがすぐに不足することです (2 GB のメモリで Eclipse を開始しました)。

これはこれを行うための現実的なアプローチですか、それとも多くのものをメモリにロードしていますか?

どうにかして仮想メモリを監視するオプションはありますか?

  • DB は小さく、物事が遅くなり、再びクラッシュしようとしているときに 4 つのエントリが含まれているため、そのようなプロジェクトで Java を好きになるという私の夢は打ち砕かれます (Java は必須です)。
4

2 に答える 2

2

メモリマップファイルを使用します。これらは多くのヒープ メモリを使用せず、読み込みが速くなる可能性があります。それらは仮想メモリを使用するだけなので、64ビットを使用している限り、これだけの問題を何千もロードできます。

FileChannel fc = new FileInputStream(fileName).getChannel();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

すべてのファイルに対してこれを実行し続けることができ、ヒープの数 KB しか使用しません。注: これは、最大 2 GB のファイルで機能します (それよりも大きい場合は、部分的にマップする必要があります)。

于 2013-06-15T14:19:43.833 に答える
2

JDK には、必要なものが既に含まれていますFileChannel#map()

さらに、MappedByteBufferを拡張ByteBufferした を返し、 を使用して内容を比較できます.equals()

Java 7 を使用すると、次のように簡単になります。

final FileChannel fc = FileChannel.open(Paths.get("/path/to/file"),
    StandardOpenOption.READ);
final ByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

(ああ、そしてそれは実装しますCloseable、したがってAutoCloseable

于 2013-06-15T14:20:40.057 に答える