web-dev-qa-db-ja.com

Javaメモリーのヒープ領域

私のアプリケーションは物理シミュレーションを実行しているため、現在かなりのメモリを消費しています。問題は、一貫して、51回目のシミュレーションで、メモリのヒープ領域が原因でJavaがエラーをスローすることです(私のプログラムは最終的に数千のシミュレーションを実行します)。

とにかく、ヒープスペースを増やすだけでなく、プログラムを変更して、実行ごとにヒープスペースがクリアされ、任意の数のシミュレーションを実行できるようにできますか?

ありがとう

-編集-

みんなありがとう。シミュレーター・ソフトウェアは実行ごとに情報をクリアしていなかったことがわかり、それらの実行をすべてアレイリストに保存しました。

47
randomafk

Java仮想マシンの起動時にヒープが割り当てられるため、ヒープをプログラムで動的に増やす方法はありません。

ただし、このコマンドは使用できます

Java -Xmx1024M YourClass

メモリを1024に設定するには

または、最小最大値を設定できます

Java -Xms256m -Xmx1024m YourClassNameHere
36

大量のメモリを使用していて、メモリリークに直面している場合は、多数のArrayListsまたはHashMapsを使用しているかどうかを確認する必要があります。

ArrayListは、 動的配列 として実装されます。 Sun/Oracleのソースコードは、新しい要素が完全なArrayListに挿入されると、元の配列の1.5倍のサイズの新しい配列が作成され、要素がコピーされることを示しています。つまり、ArrayListメソッドを呼び出さない限り、使用する各trimToSizeのスペースの最大50%を浪費する可能性があります。または、事前に挿入する要素の数がわかっている場合は、引数として初期容量を指定してコンストラクターを呼び出します。

私はHashMapのソースコードをあまり注意深く調べませんでしたが、一見すると、各HashMapの配列の長さは2のべき乗でなければならず、動的配列の別の実装になります。 HashSetは本質的にHashMapのラッパーであることに注意してください。

19
unkx80

この問題の診断に役立つさまざまなツールがあります。 JDKには JVisualVM が含まれています。これにより、実行中のプロセスにアタッチして、制御不能になっている可能性のあるオブジェクトを表示できます。 Netbeansにはラッパーがあり、かなりうまく機能します。 EclipseにはEclipse Memory Analyzerがあり、これは私が最も頻繁に使用するものですが、大きなダンプファイルを少しうまく処理しているようです。コマンドラインオプション -XX:+ HeapDumpOnOutOfMemoryError もあります。これは、プログラムがクラッシュしたときに基本的にプロセスメモリのスナップショットであるファイルを提供します。上記のツールのいずれかを使用して確認することができます。これらの種類の問題を診断する際に非常に役立ちます。

プログラムの動作の程度によっては、JVMがガベージコレクションの最適なタイミングを知らないという単純なケースである可能性があります。また、パラレルガベージコレクションのオプションも調べてください。

12
mezmo

私も同じ問題に直面しました。次の手順に従ってビルドを実行することで解決しました。

->プロジェクトを右クリックして、RunAs->実行構成を選択します

プロジェクトをBaseDirectoryとして選択します。目標の代わりにEclipse:eclipseをインストールします

-> 2番目のタブで、VM引数として-Xmx1024mを指定します。

6
PSR

この問題は、一般的なJavaメモリリークに似ていることを付け加えます。

JVMガベージコレクターがJava/Java EEアプリケーションの「無駄」なメモリを時間をかけてクリアできない場合、 OutOfMemoryError:Java heap space が結果になります。

最初に適切な診断を実行することが重要です。

  • verbose:gc を有効にします。これにより、時間の経過とともに増加するメモリパターンを理解できます。
  • JVMヒープダンプ を生成して分析します。これにより、アプリケーションのメモリフットプリントを理解し、メモリリークの原因を特定できます。
  • また、Javaプロファイラーと Plumbr などのランタイムメモリリークアナライザーを使用して、このタスクを支援することもできます。
3
P-H

-Xmxを追加してメモリを増やしてみて(Java -Xmx1024M YourClass)、必要のない変数の参照を忘れないようにしてください(メモリリーク)。

2
ivy

不要になった変数(以前のシミュレーションのデータなど)への参照を保持していますか?その場合、メモリリークが発生しています。どこでそれが起こっているのかを見つけて、変数が不要になったら変数への参照を削除することを確認する必要があります(変数がスコープ外になると自動的に発生します)。

メモリ内の以前のシミュレーションからのすべてのデータが実際に必要な場合は、ヒープサイズを増やすか、アルゴリズムを変更する必要があります。

1
Mario Duarte

Javaは、すべてのオブジェクトが参照されなくなったときに、ヒープスペースをクリアすることになっています。通常、OSに解放しませんが、内部で再利用するためにメモリを保持します。クリアされていないアレイなどがあるかどうかを確認してください。

0
Triton Man

いいえ。ヒープは、ガベージコレクターが気分に応じてクリアします。 (System.gc()を使用して)実行するように要求できますが、実行が保証されるわけではありません。

最初に-Xmx256mを設定してメモリを増やしてみてください

0
Bozho