1

txt ファイル (書籍) から読み取り、そのすべての行をリンクリストに追加しようとしています。しかし、コードを実行すると、 でメモリ不足エラーが発生しましたl.add(line);。このコードで何が間違っているのか教えていただけますか? または、LinkedList の代わりに文字列値を格納するより良い方法はありますか?

どうもありがとう!

public Book (String bookname) throws java.io.IOException{
    f = new FileReader(bookname);
    b = new BufferedReader(f);
    l = new LinkedList<String>();
    String line = b.readLine();
    while (line != null) {
        l.add(line);
    }
    b.close();
}
4

6 に答える 6

6

他の人が指摘しているように、メモリを消費する無限ループを作成しました。BufferedReader から読み取るための一般的なイディオムは次のとおりです。

String line;
while ( ( line = b.readLine() ) != null) {
    l.add(line);
}

いずれにせよ、本の内容が大きすぎて一度にメモリに収まらない可能性があると思います。Xmx 引数を使用して、JVM で使用できるメモリを増やすことができます。

java -Xmx1G MyClass

これのデフォルト値は 64 Mb ですが、最近ではあまり多くありません。

于 2011-03-04T11:53:05.350 に答える
2

たぶん交換した方がいい

while (line != null) {
    l.add(line);
}

while (line = b.readLine()) {
    l.add(line);
}
于 2011-03-04T11:56:52.420 に答える
2

メモリがなくなるまで、同じ行を何度も追加しています。

String line = b.readLine();
while (line != null) {
    l.add(line);
}

見る?line変数はループの外側で読み取られ、ループ内で変更されることはありません。

于 2011-03-04T11:54:31.487 に答える
1

変数 lineが null になることはないため、while ループが終了することはありません。これを試して:

String line = "";
while ((line = b.readLine())!= null)
{
   l.add(line);
}
b.close();
于 2011-03-04T11:55:55.297 に答える
0

mjg123に同意します。そして、メモリ不足の期待に注意してください。このような状況に対処する方法の詳細については、このブログをご覧ください ここをクリック

于 2011-03-04T13:39:11.293 に答える
0

簡単に言うと、文字列 (およびプログラム内のその他すべて) を格納するために必要なメモリが、ヒープで使用できる空きメモリの合計を超えました。

他のリストではオーバーヘッドの量がわずかに異なりますが、実際には、構造自体のメモリ要件は、そこに含まれるデータと比較して重要ではない可能性があります。つまり、別のリストの実装に切り替えると、失敗する前にさらに数行読めるようになるかもしれませんが、問題は解決しません。

Java アプリケーションのヒープ領域を増やしていない場合は、かなり低いデフォルトで実行されている可能性があります。その場合、次のコマンドライン引数を の呼び出しに提供することを検討する必要がありますjava

-Xmx512m

(ここで、 は512m512 メガバイトのヒープ領域を意味します。たとえば-Xmx2g、適切だと思われるものを使用できます。)

一方、大きなヒープ (メモリに保持する文字列の合計サイズよりもはるかに大きい) で既に実行している場合は、別の場所でメモリの問題が発生している可能性があります。本には何人のキャラクターがいますか?すべての行を格納するには、少なくともその 2 倍のバイト数が必要であり、オーバーヘッドを考慮すると、おそらくそれより 20% 程度多くなります。現在のヒープ スペースがこのデータをすべて保持できるはずであることが計算で示されている場合は、別の場所に問題がある可能性があります。それ以外の場合は、ヒープを最小限に増やすために何が必要かがわかります。

(余談ですが、大量の入力を 1 つのバッチとして処理しようとすると、メモリの問題が発生することがよくあります。8 GB のテキスト ファイルを処理したい場合はどうすればよいでしょうか?多くの場合、ある種のストリームで、小さなチャンクを順次処理する方が適切です。たとえば、すべての文字を大文字にして別のファイルに書き戻したい場合は、最初に本全体をメモリに読み込むのではなく、一度に 1 行ずつ行うことができます。)

于 2011-03-04T11:54:05.590 に答える