2016-05-01 14 views
0

私はwhy is it bad practice to call System.gc()と他の多くのものを読んでいます。 this oneは、実際には悲惨な誤用であるSystem.gc()を説明しています。しかし、GC takes too longと、長い休止を避ける場合、例えばavoiding garbageである場合は、まったく簡単ではなく、コードを保守しにくくする場合があります。手動でGCを呼び出す手動GC呼び出しの使用例?

私見では、次の一般的なシナリオで結構です:

  • 彼らの前にフェイルオーバーを持つ複数の交換可能webservesがあります。
  • すべてのサーバーは数ギガバイトのヒープを使用し、STWの一時停止は平均的な要求よりもはるかに時間がかかります。
  • GCがいつ起きるかは、フェールオーバーでは分かりません。
  • フェールオーバーは、通知されたときにサーバーを免除することができます。

アルゴリズムは、サーバーを定期的に選択し、それ以上の要求を送信しないようにして、実行要求を完了させ、GCを実行させ、サーバーを再起動させます。

何か不足していると思いますか? 1,2

代替手段は何ですか?

  1. 長時間実行されるリクエストは問題になる可能性がありますが、それがないものとします。あるいは、単にGCが取るものに匹敵するいくつかの期間に待つことを制限する。遅い要求をさらに遅くすることはあまりにも悪くはありません。

  2. -XX:+DisableExplicitGCのようなオプションは、アルゴリズムを役に立たなくするかもしれませんが、使用しないでください(私の使用例には私が担当する専用サーバーが含まれています)。

+1

imoが壊れていない場合は修正しないでください。メモリのためにパフォーマンスのボトルネックが見えない場合は、なぜそれについて心配ですか? –

+0

@MitchWeaver合意しておけば、自動GCがあなたが望むことをしないと判断した場合にのみ、コントロールを試みるべきです。 –

+0

@MitchWeaver私はそれをプレーニングと呼んでいます。多くのプロジェクトではGCに問題がありますので、それらも期待する必要があります。良い解決策があることを知っていると、今私はずっと心配していません。私の質問の理由は、誰もが "Heaven Calling GC!を禁止しました!"などの主張をしていたので、私は確認を求めていました。 – maaartinus

答えて

2

私はGCを非定型的に使用しています。

取引日には小さなものであっても、収集を避けたいと考えています。これを行う方法は、1秒あたり300KB未満のゴミを作成することです。これは1時間あたり約1 GB、または1日あたり最大24 GBです。 24 GBのEden空間を使用する場合は、マイナー/メジャーGCが存在しないことを意味します。しかし、GCが確実に計画され、受け入れられるようにするには、毎朝午前5時にSystem.gc()が呼び出され、次の日はきれいなエデンスペースがあります。

予想よりも多くのゴミを作成すると、時間がかかります。データソースへの再接続に失敗し、マイナーコレクションの数が少なくなる可能性があります。しかし、これは何かがうまくいかないときにのみ起こります。ごみを回避することによって、より詳細http://vanillajava.blogspot.co.uk/2011/06/how-to-avoid-garbage-collection.html

については

は正確に些細なことではないし、維持するためにコードが難しくなります。

ごみを完全に避けることはほぼ不可能です。しかし、300 KB/sはJVMにとって難しくありません。 (最近、1台のマシンで24GBのEdenスペースを持つ複数のJVMを持つことができます)

ごみを50 KB/s以下に抑えることができれば、GCで一週間中実行できます。

定期的にサーバーを選択し、それ以上の要求を送信しないようにして、実行要求を完了させ、GCを実行させ、サーバーを再度アクティブにします。

GCをSLA条件を満たしていないとして扱うことができます。この場合、サーバーがクラスタから発生しようとしていると判断したらサーバーを削除し、フルGCを実行してクラスタに戻すことができます。

2

しかし、あなたが若いだけ、混合/同時期とフルGCによって引き起こさポーズを区別する必要がありGC時間がかかりすぎるときのケースがあり、長いポーズ

を回避することができます。

ほとんどの場合、それは多くの場合、いくつかのGC-チューニングと大きなアロケーションバーストを避けるために、コードの最適化を達成することができるあなたは、他のものは許容されている間、避けたいフルGC、です。原則としてG1で

は、混合/若いサイクルに永遠に実行することができますし、フルGCは、ソフトの故障と考えられます。 CMSは、チューニングを慎重にして何日も行うことができますが、最終的には断片化に陥り、圧縮に完全なGCが必要になることがあります。

若いGCが一時停止しても許容されない場合や、ゴミが重なって許容可能な休止時間で処理できない場合は、あなたが考えている方法が有効です。

GC管理のネイティブリソースなど、GCを手動でトリガーするための他のユースケースもあります。ダイレクト・バイト・バッファですが、一般にはかなり面倒です。

System.gc()のコールがすべて均等に作成されるわけではありません。また、ExplicitGCInvokesConcurrentオプションもあります。

関連する問題