質問

非常に大きな画像をメモリにロードするコードがあります。したがって、電話するのは合理的であるように思えました

System.gc();

画像をロードする前に。私の知る限りでは、問題なく動作しています。

昨日、私は非常に便利なソフトウェアを使用することにしました。 バグを探す コードをスキャンし、バグの原因となる可能性のある問題や、一般的に推奨されない戦略を報告します。問題は、私が言及したこのコード部分が報告されることです。説明はこうです。

...ガベージコレクションを強制します。を除いて非常に疑わしい ベンチマークコード

さらに詳しく説明します。

コードがガベージを明示的に呼び出す 徴収。特定の用途を除き、 ベンチマーク、これは非常に疑わしいです。

過去には、人々が ガベージを明示的に呼び出した Collector を close や finalizeメソッドは、巨大な パフォーマンスブラックホール。廃物 コレクションには費用がかかる場合があります。任意 何百人もの強制的な状況や 何千ものガベージコレクションは、 機械を這わせます。

そこで私の質問は次のとおりです。 このような場合、プログラムでガベージ コレクターを呼び出すのはダメでしょうか?私のコードはそれを一度だけ呼び出すだけで、そのメソッドが使用されることはめったにありません。そして、それを呼び出すことができない場合、非常にメモリを大量に消費する操作を実行する前にできるだけ多くのメモリが必要で、その前にできるだけ多くのメモリを解放する必要がある場合はどうすればよいでしょうか?

役に立ちましたか?

解決

System.gc() を使用するとパフォーマンスが向上しましたか?画像をロードする前に収集する必要のあるオブジェクトはおそらくそれほど多くないので、そうは思いません。

通常、最新のガベージ コレクターはいつ実行するかを最もよく知っているため、よほどの理由がない限り、コレクションを強制的に実行すべきではありません。(たとえば、そのプラグインが提案するベンチマーク アプリケーション)

ところで:System.gc() を呼び出すと、VM は「完全」または「大規模」コレクションを実行することが推奨されます。これは、すべてのスレッドがすぐに停止されることを意味します。それ以外の場合は、おそらく「小さな」ガベージ コレクションのみが作成され、すべてのスレッドは停止されません。

-verbose:gc を指定してプログラムを実行して、収集されるバイト数を確認します。

ガベージ コレクションに関する多くの技術情報もここにあります。http://java.sun.com/developer/technicalArticles/Programming/GCPortal/

他のヒント

通常、GC はユーザーよりも賢いため、ランタイムが決定するたびに GC を実行させる方が良いでしょう。ランタイムがメモリを必要とする場合、ランタイム自体が GC を実行します。

ガベージ コレクターを呼び出しても問題ありません。そこから「問題」が発生することはありません。ただし、その呼び出しで割り当てられたデータのデフラグも処理しない限り、パフォーマンスが大幅に向上するとは思えません。それは分かりません。

この場合に行うべきことは、コードのプロファイルを作成することです。何度か実行して、どのような結果が得られるかを確認してください。

通常、ガベージ コレクターを妨害すべきではありません。イメージをロードする前にメモリを解放する必要がある場合は、ガベージ コレクターがそれを実行します。

いずれにせよ、一度だけ実行するのであれば、おそらくパフォーマンスに大きな影響を与えることはありません。ループ内で実行されることの方がはるかに重要です。

すでにたくさんの良いアドバイスをいただいていますが、繰り返しは述べません。

アプリケーションが一瞬完全に停止するなど、実際に GC で問題が発生した場合は、次の手順を実行します。1.System.gc() への呼び出しがないことを確認します。2.gc を構成するためのさまざまなオプションを確認してください。それらは周りにたくさんあり、GCを強制するよりもはるかに役に立ちます。

大きなオブジェクトをできるだけ早く gc できるようにしてください。つまり、変数を null に設定するか、変数をスコープ外にします。これは助かります!

メモリ割り当てが失敗した場合、GC サイクルが開始され、割り当てが再試行されます。

一般的には、いいえ。System.gc() を呼び出すことは適切ではありません。ただし、それが意味があると感じたケースがいくつかありました。

私が作成したソフトウェアには、パフォーマンス追跡レイヤーが組み込まれています。これは主に自動テスト中に使用されますが、診断目的で現場で使用することもできます。テスト間または特定の実行後に System.gc を数回呼び出して、まだ存在するメモリを記録します。これは、長期にわたるメモリ消費の傾向線を監視するための基本的なメモリ フット プリント ベンチマークを提供します。これは一部の外部 JVM インターフェイスを使用して実行できますが、適切な場所で実行する方が簡単であり、正確な数値は必要ありません。

はるかに古いシステムでは、72 個を超える個別の JVM を使用できました (そうです、72 個です。構築時にそうするのには十分な理由がありました)。そのシステムでは、72 個すべての JVM でヒープをフリーフロートのままにすると、過剰な (物理メモリをはるかに超える) 総メモリ消費量が発生する可能性があります。System.gc() は、大量のデータを実行する合間に呼び出され、ヒープの増大を防ぐために JVM を平均に近づけようとしました (ヒープを制限するという別の方向性も考えられますが、その場合、実装者はサイトごとにさらに多くの設定を行う必要があり、正しく動作させるために、内部で何が起こっているかをもっと認識し、負荷がかかったときにシステムが失敗しないようにする必要があります)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top