大規模なデータセットで複雑な Java アプリケーションを実行しています。アプリケーションはかなり高速に実行されますが、時間の経過とともに大量のメモリを消費し、速度が低下するようです。アプリケーションを再起動せずに JVM ガベージ コレクタを実行する方法はありますか?
8 に答える
いいえ、ガベージ コレクションを強制することはできません。
使っても
System.gc();
ガベージ コレクションのリクエストを行うことはできますが、それを行うかどうかは JVM に依存します。
また、ガベージ コレクターは、必要に応じて未使用のメモリを収集するのに十分なほどスマートなので、ガベージ コレクションを強制する代わりに、オブジェクトを間違った方法で処理しているかどうかを確認する必要があります。
オブジェクトを間違った方法で処理している場合 (不要なオブジェクトへの参照を維持するなど)、メモリを解放するために JVM ができることはほとんどありません。
ドクから
gc メソッドを呼び出すことは、Java 仮想マシンが未使用のオブジェクトをリサイクルして、現在占有しているメモリをすばやく再利用できるようにすることを示唆しています。メソッド呼び出しから制御が戻ると、Java 仮想マシンは、 破棄されたすべてのオブジェクトからスペースを再利用するために最善を尽くしています。
ドキュメントに関する未 解決のバグSystem.gc()
System.gc() のドキュメントは非常に誤解を招くものであり、System.gc() を決して呼び出さないという推奨される方法について言及していません。
言語の選択により、 System.gc() が呼び出されたときの動作と、どのような外部要因が動作に影響を与えるかが不明確になります。
JVMに強制的にメモリを解放させる必要があると思われる場合に役立つリンクはほとんど
ありません
。
すべてが1を言い
ます.JavaでGCを制御することはできませんSystem.gc()
。保証さえしません。
2. また、強制的に実行すると、パフォーマンスに悪影響を及ぼす可能性があります。
3. 設計を再検討し、JVM に仕事を任せてください :)
アプリケーションはかなり高速に動作しますが、時間が経つにつれて大量のメモリを消費し、速度が低下するようです。
これらは、Javaメモリの典型的な症状です。アプリケーションのどこかに、成長し続けるデータ構造がある可能性があります。ヒープがいっぱいに近づくと、JVMは、GCの実行に費やす時間の割合が増え、スペースを(無駄に)クローバックしようとします。
GCはデータ構造を収集できないため、GCを強制してもこれは修正されません。実際、GCを強制的に実行すると、アプリケーションの速度が低下します。
この問題の解決策は、メモリリークの原因を特定し、それを修正することです。
パフォーマンスの向上/低下は、ガベージ コレクションが必要な頻度、jvm のメモリ量、およびプログラムが必要とする量によって異なります。
System.gc() を呼び出すときのガベージ コレクションの確実性はありません (インタープリターへのヒントにすぎません) が、少なくとも可能性はあります。十分な数の呼び出しがあれば、システム設定だけで統計的に導き出されたパフォーマンス乗数を達成できます。
以下のグラフは、サンプルプログラムの実行の消費量を示しており、jvm には、各試行にそれぞれ 1GB (gc なし)、1GB (gc)、3GB (gc)、3GB (gc なし) ヒープのみが与えられました。
最初、プログラムが 3.75GB のメモリを必要としているのに、jvm に 1GB のメモリしか与えられなかった場合、ガベージ管理が少ないとオブジェクトの作成速度が低下するため、プロデューサー スレッド プールがジョブを完了するのに 50 秒以上かかりました。
2 番目の例は、System.gc() が 150MB のオブジェクト データの生成ごとに呼び出されるため、約 40% 高速です。
3 番目の例では、System.gc() をオンにしたまま、jvm に 3GB のメモリ空間が与えられます。メモリを増やすと、期待どおりのパフォーマンスが得られます。
しかし、同じ 3GB 環境で System.gc() をオフにすると、高速になりました。
強制することはできなくても、System.g() を十分に長く試してみると、パフォーマンスが何パーセントか向上または低下する可能性があります。少なくとも、最新の jvm を搭載した私の windows-7 64 ビット オペレーティング システムでは。
の
System.gc()
Java で呼び出し、VM にガベージ コレクションの実行を提案します。ただし、実際にそれを行うことを保証するものではありません。それにもかかわらず、あなたが持っている最善の解決策。他の回答で述べたように、jvisualvm ユーティリティ (JDK 6 update 7 以降の JDK に存在) は、ガベージ機能も提供します。
編集:
あなたの質問はトピックに対する私の欲求を開き、私はこのリソースに出くわしました:
中継するべきではありませんSystem.gc()
- GC を強制的に実行する必要があると感じた場合、通常はコード/設計に問題があることを意味します。未使用のオブジェクトを作成する準備ができていれば、GC が実行されてクリアされます。設計を確認し、メモリ管理についてさらに検討し、オブジェクト参照のループも調べてください。
ガベージコレクターは自動的に実行されます。ガベージコレクターを強制することはできません。
I do not suggest that you do that but to force the garbage collector to run from within your java code you can just use all the available memory, this works because the garbage collector will run before the JVM throws OutOfMemoryError...
try {
List<Object> tempList = new ArrayList<Object>();
while (true) {
tempList.add(new byte[Integer.MAX_VALUE]);
}
} catch (OutOfMemoryError OME) {
// OK, Garbage Collector will have run now...
}