129

Javaではガベージコレクションが自動化されていることを知っています。System.gc()しかし、コードを呼び出すと、その時点で JVM がガベージ コレクションの実行を決定する場合としない場合があることを理解しました。これはどのように正確に機能しますか?JVM が GC を実行する (または実行しない) ことを正確に決定する基準/パラメーターはSystem.gc()何ですか?

これをコードに入れることをお勧めする例はありますか?

4

16 に答える 16

61

実際には、通常はガベージ コレクションを実行することを決定します。答えは、実行している JVM、JVM のモード、使用しているガベージ コレクション アルゴリズムなど、多くの要因によって異なります。

私はあなたのコードでそれに依存しません。JVM が OutOfMemoryError をスローしようとしている場合、System.gc() を呼び出しても停止しません。これは、ガベージ コレクターが極端になる前に可能な限り解放しようとするためです。実際に使用されているのを見たのは、ユーザーがクリックできるボタンに接続されている IDE だけですが、それでもそれほど有用ではありません。

于 2008-09-15T20:23:41.663 に答える
30

System.gc() を呼び出す意味があると私が思いつく唯一の例は、アプリケーションをプロファイリングしてメモリ リークの可能性を検索する場合です。プロファイラーは、メモリ スナップショットを取得する直前にこのメソッドを呼び出すと思います。

于 2008-09-15T20:36:59.993 に答える
29

Java で GC を制御することはできません。VM が決定します。System.gc()必要なケースに出くわしたことはありません。System.gc()呼び出しは単に VM がガベージ コレクションを実行し、完全なガベージ コレクション (多世代ヒープ内の古い世代と新しい世代) も実行することを示唆しているため、実際には必要以上に多くの CPU サイクルが消費される可能性があります

場合によっては、大きな負荷がかかる前にアプリケーションが数分間アイドル状態になることがわかっているため、今すぐ完全なコレクションを実行することを VM に提案することが理にかなっている場合があります。たとえば、アプリケーションの起動中に大量の一時オブジェクトを初期化した直後 (つまり、大量の情報をキャッシュしただけで、1 分間ほどはあまりアクティビティが得られないことがわかっています)。Eclipse の起動などの IDE を考えてみてください。初期化に多くの作業を行うため、おそらく初期化の直後にその時点で完全な gc を実行するのが理にかなっています。

于 2008-09-15T20:27:20.720 に答える
26

Java 言語仕様では、 を呼び出したときに JVM が GC を開始することは保証されていませんSystem.gc()。これが、「その時点で GC を実行するか決定しないか」の理由です。

ここで、Oracle JVM のバックボーンであるOpenJDK ソース コードSystem.gc()を見ると、 への呼び出しが GC サイクルを開始することがわかります。J9 などの別の JVM を使用している場合は、それらのドキュメントを調べて答えを見つける必要があります。たとえば、Azul の JVM には継続的に実行されるガベージ コレクターがあるため、 を呼び出してSystem.gc()も何も起こりません。

他の回答では、JConsole または VisualVM で GC を開始することに言及しています。基本的に、これらのツールは へのリモート呼び出しを行いSystem.gc()ます。

通常、アプリケーションのセマンティクスを台無しにするため、コードからガベージ コレクション サイクルを開始することは望ましくありません。アプリケーションはいくつかのビジネス処理を行い、JVM はメモリ管理を担当します。これらの懸念事項は分けておく必要があります (アプリケーションにメモリ管理を行わせず、ビジネスに集中してください)。

ただし、 の呼び出しが理解できる場合はほとんどありSystem.gc()ません。たとえば、マイクロベンチマークを考えてみましょう。マイクロベンチマークの途中で GC サイクルが発生することは誰も望んでいません。そのため、各測定の間に GC サイクルをトリガーして、すべての測定が空のヒープから開始されるようにすることができます。

于 2013-05-11T10:36:33.910 に答える
17

に電話する場合は十分に注意する必要がありますSystem.gc()。これを呼び出すと、不要なパフォーマンスの問題がアプリケーションに追加される可能性があり、実際にコレクションを実行する保証はありません。実際にはSystem.gc()、java 引数を介して明示的に無効にすることができます-XX:+DisableExplicitGC

ガベージ コレクションの詳細については、Java HotSpot Garbage Collectionで入手できるドキュメントを一読することを強くお勧めします。

于 2008-09-15T20:36:49.200 に答える
12

System.gc()VMによって実装され、それが行うことは実装固有です。たとえば、実装者は単純に戻って何もしない可能性があります。

手動収集をいつ発行するかについては、たとえば、多数の小さなコレクションを含む大規模なコレクションを破棄し Map<String,<LinkedList>> 、パフォーマンス ヒットを試して取得したい場合にのみ、これを実行する必要があります。ありますが、ほとんどの場合、心配する必要はありません。GC は、悲しいことに、ほとんどの場合、あなたよりもよく知っています。

于 2008-09-15T20:25:10.117 に答える
5

ほとんどの JVM は GC を開始します (-XX:DiableExplicitGC および -XX:+ExplicitGCInvokesConcurrent スイッチによって異なります)。しかし、後でより良い実装を可能にするために、仕様はあまり明確に定義されていません。

仕様には明確化が必要です:バグ #6668279: (仕様) System.gc() は、使用を推奨せず、動作を保証しないことを示す必要があります

内部的には、gc メソッドは RMI と NIO によって使用され、同期実行が必要です。これは現在議論中です:

バグ #5025281: System.gc() が同時 (stop-the-world ではない) 完全なコレクションをトリガーできるようにする

于 2008-09-16T18:36:52.597 に答える
4

Garbage CollectionJavaデスクトップ/ラップトップ/サーバーで Java でコード化されたソフトウェアを実行している場合に適しています。System.gc()またはRuntime.getRuntime().gc()で呼び出すことができますJava

これらの呼び出しのいずれも、何かを行うことが保証されていないことに注意してください。これらは、jvm がガベージ コレクターを実行するための単なる提案です。GC を実行するかどうかは JVM 次第です。簡単に言えば、いつ実行されるかはわかりません。より長い答え: 時間があれば、JVM は gc を実行します。

同じことがAndroidにも当てはまると思います。ただし、これによりシステムの速度が低下する可能性があります。

于 2013-04-27T12:05:48.767 に答える
2

通常、VM は OutOfMemoryException をスローする前にガベージ コレクションを自動的に実行するため、明示的な呼び出しを追加しても、パフォーマンス ヒットが以前の時点に移動する可能性があるという点を除いて、役に立ちません。

しかし、関連する可能性のあるケースに遭遇したと思います。ただし、効果があるかどうかはまだテストしていないため、わかりません。

ファイルをメモリマップすると、十分な大きさのメモリブロックが利用できない場合、 map() 呼び出しが IOException をスローすると思います。map() ファイルの直前のガベージ コレクションは、それを防ぐのに役立つかもしれないと思います。どう思いますか?

于 2009-02-10T13:20:10.290 に答える
2

ガベージ コレクションを強制することはできません。System.gc はガベージ コレクションに vm を提案しているだけですが、実際にはメカニズムがいつ実行されるかは誰にもわかりません。これは JSR 仕様で規定されているとおりです。

于 2010-10-31T03:53:53.283 に答える
2

時間をかけてさまざまなガベージ コレクション設定をテストすることには多くのことが言えますが、上で述べたように、通常はそうするのは役に立ちません。

私は現在、メモリが制限された環境と比較的大量のデータを含むプロジェクトに取り組んでいます。環境を限界まで押し上げる大きなデータがいくつかあります。メモリ使用量を下げることはできましたが、理論的には問題なく動作するはずですが、それでもヒープ スペース エラーが発生します。詳細な GC オプションは、ガベージ コレクションを試みていることを示していましたが、役に立ちませんでした。デバッガーで System.gc() を実行すると、利用可能な「十分な」メモリが十分にあることを確認できました...余分な量ではありませんが、十分です。

したがって、アプリケーションが System.gc() を呼び出すのは、データの処理に必要な大きなバッファーが割り当てられるコードのセグメントに入ろうとしているときだけです。持つことが保証されています。特に、少なくとも 300 MB が静的データによって占められている 1 GB 環境を見ています。非静的データの大部分は実行に関連しています。起源。これはすべて自動データ変換プロセスの一部であるため、長期的にはデータはすべて比較的短期間存在します。

残念ながら、ガベージ コレクターを調整するためのさまざまなオプションに関する情報は利用可能ですが、それは主に実験的なプロセスのようであり、これらの特定の状況を処理する方法を理解するために必要な低レベルの詳細は簡単には取得できません。

とはいえ、私は System.gc() を使用していますが、それでもコマンド ライン パラメーターを使用して調整を続け、アプリケーションの全体的な処理時間を比較的大幅に改善することができました。より大きなデータ ブロックを操作することによって生じるつまずきのブロック。そうは言っても、 System.gc() はツールです....非常に信頼性の低いツールであり、使用方法に注意しないと、頻繁に機能しないことを望むでしょう。

于 2011-03-07T09:00:13.667 に答える
2

が呼び出されたかどうかを知りたい場合System.gc()は、新しい Java 7 update 4 で、JVM がガベージ コレクションを実行したときに通知を受け取ることができます。

GarbageCollectorMXBeanクラスが Java 7 update 4 で導入されたかどうかは 100% 確信が持てません。リリース ノートで見つけることができなかったからですが、javaperformancetuning .com サイトで情報を見つけました。

于 2012-07-25T12:01:22.337 に答える
0

明示的なGCを実行するのが良い場合、具体的な例を考えることはできません。

一般に、明示的なGCを実行すると、実際には良いよりも害が大きくなる可能性があります。これは、明示的なgcが完全なコレクションをトリガーし、すべてのオブジェクトを通過するのにかなり長い時間がかかるためです。この明示的なgcが繰り返し呼び出されると、完全なGCの実行に多くの時間が費やされるため、アプリケーションの速度が低下する可能性があります。

または、ヒープアナライザーでヒープを調べ、ライブラリコンポーネントが明示的なGCを呼び出していると思われる場合は、JVMパラメーターにgc = -XX:+DisableExplicitGCを追加してオフにすることができます。

于 2008-09-15T20:32:20.427 に答える
0

system.gc が機能している間、世界が停止します。すべての応答が停止されるため、ガベージ コレクターはすべてのオブジェクトをスキャンして、削除が必要かどうかを確認できます。アプリケーションが Web プロジェクトの場合、gc が終了するまですべてのリクエストが停止します。これにより、Web プロジェクトが monent で機能しなくなります。

于 2012-07-06T09:57:38.280 に答える