「java.lang.OutOfMemoryError: Java heap space」エラーに対処するにはどうすればいいですか? 質問する

「java.lang.OutOfMemoryError: Java heap space」エラーに対処するにはどうすればいいですか? 質問する

私はJava 5でクライアントサイドのSwingアプリケーション(グラフィカルフォントデザイナー)を書いています。最近、メモリ使用量を節約していないためにエラーが発生しています。ユーザーは無制限の数のファイルを開くことができ、プログラムは開いたオブジェクトをメモリ内に保持します。簡単に調べたところ、java.lang.OutOfMemoryError: Java heap space5.0 Java 仮想マシンの人間工学また、Windows マシンでは、JVM のデフォルトの最大ヒープ サイズが であると言っている人もいます64MB

このような状況では、この制約にどのように対処すればよいでしょうか?

Java のコマンド ラインオプションを使用して最大ヒープ サイズを増やすことはできますが、そのためには使用可能な RAM を調べ、起動プログラムまたはスクリプトを作成する必要があります。また、有限の最大値まで増やしても、最終的に問題は解決しません。

コードの一部を書き直して、オブジェクトを頻繁にファイル システムに保持し (データベースを使用するのも同じことです)、メモリを解放することもできます。うまくいくかもしれませんが、おそらく作業量もかなり多くなります。

上記のアイデアの詳細や、自動仮想メモリ、ヒープ サイズの動的な拡張などの代替案を教えていただければ幸いです。

ベストアンサー1

結局のところ、どのプラットフォームで実行しているかに関係なく、使用できるヒープの最大値は常に有限です。Windows 32 ビットでは、これは約2GB(ヒープではなく、プロセスあたりのメモリの合計量) です。たまたま Java がデフォルトを小さくすることを選択しただけです (おそらく、プログラマーがこの問題に遭遇し、正確に何を実行しているかを調べることなく、メモリ割り当てが暴走するプログラムを作成できないようにするためです)。

したがって、必要なメモリ量を決定するか、使用しているメモリ量を減らすために実行できるアプローチはいくつかあります。Java や C# などのガベージ コレクション言語でよくある間違いの 1 つは、使用しなくなったオブジェクトへの参照を保持したり代わりに再利用できるオブジェクトを多数割り当てたりすることです。オブジェクトが参照を保持している限り、ガベージ コレクターはオブジェクトを削除しないため、オブジェクトはヒープ領域を使用し続けます。

この場合、Java メモリ プロファイラを使用して、プログラム内のどのメソッドが大量のオブジェクトを割り当てているかを判断し、それらのメソッドが参照されないようにする方法があるか、またはそもそも割り当てないようにする方法があるかを判断します。私が過去に使用したオプションの 1 つは「JMP」です。http://www.khelekore.org/jmp/ より

何らかの理由でこれらのオブジェクトを割り当てており、参照を保持する必要があると判断した場合 (実行内容によってはこのケースになる場合があります)、プログラムを起動するときに最大ヒープ サイズを増やすだけで済みます。ただし、メモリ プロファイリングを実行して、オブジェクトがどのように割り当てられているかを理解すると、必要なメモリの量についてより適切なアイデアが得られるはずです。

一般的に、プログラムが有限量のメモリで実行されることを保証できない場合 (おそらく入力サイズによる)、常にこの問題に遭遇します。これらすべてを試した後でのみ、オブジェクトをディスクなどにキャッシュすることを検討する必要があります。この時点で、何かに対して「XGB のメモリが必要」と言う十分な理由があり、アルゴリズムやメモリ割り当てパターンを改善しても回避できないはずです。通常、これは大規模なデータセット (データベースや科学分析プログラムなど) で動作するアルゴリズムにのみ当てはまり、キャッシュやメモリ マップ IO などのテクニックが役立ちます。

おすすめ記事