web-dev-qa-db-ja.com

Java本番環境のG1ガベージコレクション

Java 7はデフォルトで新しいG1ガベージコレクションを使用するため、Java 「GCの一時停止時間。実際にG1を運用環境に実装した人はいますか。あなたの経験はどうでしたか?

公平を期すために、GCが非常に長い間一時停止するのを目にしたのは、ワークステーションが持っているよりもはるかに大きい非常に大きなヒープ上だけです。私の質問を明確にするため。 G1は数百GBのヒープへのゲートウェイを開きますか?結核?

89
benstpierre

G1のポイントは、一時停止時間を短くすることであり、最大一時停止時間のターゲットを指定する機能があるように思えます。

ガベージコレクションは、単なる「ちょっと、いっぱいです。一度にすべてを動かしてやり直しましょう」という単純なものではありません。これは、非常に複雑でマルチレベルのバックグラウンドスレッドシステムです。一時停止することなく、バックグラウンドで多くのメンテナンスを実行できます。また、実行時にシステムの予想パターンの知識を使用して、ほとんどのオブジェクトが作成直後に消滅するなどの支援を行います。

GCの一時停止時間は、今後のリリースで悪化することなく改善され続けると思います。

編集:

読み直すと、Java daily--Eclipse、Azureus、開発中のアプリを使用していますが、一時停止を確認してから長い時間が経ちました。 、しかし、私はすべての一時停止を意味します。

Windows Explorerを右クリックしたとき、または(ときどき)特定のUSBハードウェアを接続したときにJavaで接続したときに一時停止が発生しました。

GCはまだ誰かの問題ですか?

34
Bill K

重いアプリケーションでテストしてきました:ヒープに60-70GBを割り当て、いつでも20-50GBを使用します。これらの種類のアプリケーションでは、走行距離が異なる可能性があると言っても過言ではありません。 LinuxでJDK 1.6_22を実行しています。マイナーバージョンは重要です。約1.6_20以前には、ランダムなNullPointerExceptionsを引き起こすバグがG1にありました。

ほとんどの場合、一時停止ターゲット内に収めることが非常に良いことがわかりました。デフォルトは100ミリ秒(0.1秒)の一時停止のように見えますが、その半分を実行するように指示しています(-XX:MaxGCPauseMillis = 50)。ただし、メモリが非常に少なくなると、パニック状態になり、完全停止のガベージコレクションが実行されます。 65GBでは、30秒から2分かかります。 (CPUの数はおそらく違いはありません。おそらくバス速度によって制限されます。)

CMS(デフォルトのサーバーGCではありませんが、Webサーバーやその他のリアルタイムアプリケーション用である必要があります)と比較すると、通常の一時停止ははるかに予測しやすく、はるかに短くすることができます。これまでのところ、私はCMSで大きな一時停止をうまく運んでいますが、それはランダムかもしれません。 24時間ごとに数回しか見ていません。現時点ではどちらが本番環境に適しているかわかりませんが、おそらくG1です。 Oracleが引き続きチューニングを行っている場合、最終的にG1が最終的な勝者になると思います。

既存のガベージコレクターに問題がない場合は、現時点でG1を検討する理由はありません。 GUIアプリケーションなどの低遅延アプリケーションを実行している場合、G1がおそらく正しい選択であり、MaxGCPauseMillisは非常に低く設定されています。バッチモードアプリケーションを実行している場合、G1は何も購入しません。

58
David Leppik

実稼働環境でG1をテストしたことはありませんが、「巨大な」ヒープがない場合、GCはすでに問題があるとコメントしたいと思います。具体的には、たとえば2または4ギグだけのサービスは、GCによって深刻な影響を受ける可能性があります。通常、若い世代のGCは1桁のミリ秒(または最大で2桁)で終了するため、問題はありません。ただし、1ギガバイト以上の旧世代サイズでは数秒かかるため、旧世代のコレクションははるかに問題があります。

現在:理論的には、CMSはほとんどの操作を同時に実行できるため、多くの場合に役立ちます。ただし、時間が経つにつれて、これを行うことができず、「世界を停止する」コレクションにフォールバックしなければならない場合があります。そして、それが起こったら(たとえば、1時間後-頻繁ではないが、それでも頻繁に)、まあ、f *** ingの帽子を握ってください。 1分以上かかる場合があります。これは、最大遅延を制限しようとするサービスにとって特に問題です。たとえば、リクエストの処理に25ミリ秒かかる代わりに、10秒以上かかります。 in辱的なクライアントに傷害を加えると、リクエストがタイムアウトして再試行されることが多く、さらなる問題(「シットストーム」とも呼ばれます)につながります。

これは、G1が大いに役立つと期待されていた領域の1つです。ストレージとメッセージのディスパッチのためのクラウドサービスを提供する大企業で働いていました。また、CMSを使用することはできませんでした。なぜなら、ほとんどの場合、並列品種よりもうまく機能していましたが、これらのメルトダウンがあったからです。約1時間、物事はナイスでした。そして、ものがファンを襲います...そしてサービスはクラスターに基づいていたため、1つのノードがトラブルになったとき、通常は他のノードが続きました(GC誘導タイムアウトは他のノードがノードがクラッシュしたと信じ、再ルーティングにつながるため)。

GCはアプリにとってそれほど大きな問題ではないと思いますし、クラスター化されていないサービスでさえもそれほど影響を受けないでしょう。しかし、ますます多くのシステムがクラスター化され(特にNoSQLデータストアのおかげ)、ヒープサイズが拡大しています。 OldGen GCは、ヒープサイズと超線形に関連しています(つまり、ヒープサイズを2倍にするとGC時間は2倍以上になり、ライブデータセットのサイズも2倍になります)。

14
StaxMan

AzulのCTOであるGil Teneには、ガベージコレクションに関連する問題の概要とさまざまな解決策のレビューがあります Javaガベージコレクションとそれについてできること プレゼンテーション、およびこの記事には追加の詳細があります: http://www.infoq.com/articles/azul_gc_in_detail

Zing JVMのAzulのC4ガーベッジコレクターは、並列と同時の両方であり、新世代と旧世代の両方で同じGCメカニズムを使用し、両方の場合で同時に動作して圧縮します。最も重要なことは、C4にはストップワールドフォールバックがないことです。すべての圧縮は、実行中のアプリケーションと同時に実行されます。非常に大規模(数百GBytes)のGC一時停止時間(10ミリ秒未満)を実行しており、アプリケーションによっては1〜2ミリ秒未満の場合があります。

CMSとG1の問題は、ある時点でJavaヒープメモリを圧縮する必要があり、これらのガベージコレクターが両方ともワールド/ STWを停止(つまりアプリケーションを一時停止)して圧縮を実行することです。そのため、CMSとG1はSTWの一時停止をプッシュできますが、それらを削除しません。しかし、AzulのC4は、STWの一時停止を完全に削除します。

また、以前の回答で作成されたステートメントを修正するために、Zingはオペレーティングシステムの変更を必要としません。変更されていないLinuxディストリビューションでは、他のJVMと同様に実行されます。

13
Scott Sellers

ほぼ2年前からG1GCを使用しています。ミッションクリティカルなトランザクション処理システムで優れたパフォーマンスを発揮し、高スループット、低休止、同時実行性、および最適化されたヘビーメモリ管理の優れたサポートであることが証明されました。

次のJVM設定を使用しています。

-server -Xms512m -Xmx3076m -XX:NewRatio=50 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -XX:+AggressiveOpts -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000 -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime

更新済み

-d64 -server -Xss4m -Xms1024m -Xmx4096m -XX:NewRatio=50 -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+HeapDumpOnOutOfMemoryError -XX:-DisableExplicitGC -XX:+AggressiveOpts -Xnoclassgc -XX:+UseNUMA -XX:+UseFastAccessorMethods -XX:ReservedCodeCacheSize=48m -XX:+UseStringCache -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000
12
emkays

G1コレクターは、完全なコレクションの影響を軽減します。完全なコレクションの必要性をすでに減らしたアプリケーションがある場合、同時マップスイープコレクターも同様に優れており、私の経験ではマイナーコレクション時間が短くなっています。

8
Peter Lawrey

JDK7u4を開始するG1が正式にサポートされたようです。JDK7u4のRNを参照してください http://www.Oracle.com/technetwork/Java/javase/7u4-relnotes-1575007.html

まだ大きなJVMのテストから、調整されたCMSはG1よりも優れた動作をしますが、より良くなると思います。

5
Bubi S

Terracotta Big MemoryプロジェクトにG1 Garbage Collectorを実装しました。さまざまなタイプのコレクターで作業している間、G1は600ms未満の応答時間で最高の結果をもたらしました。

テスト結果を見つけることができます(合計26) こちら

それが役に立てば幸い。

4
Spanglish

最近私はから移動されました

JDK 1.7.45を使用するサーバー上の4Gヒープおよび8コアプロセッサを使用したCMS to G1GC

(JDK 1.8.x G1GCは1.7よりも優先されますが、いくつかの制限があるため、1.7.45バージョンに固執する必要があります)

以下の主要なパラメータを設定し、他のすべてのパラメータをデフォルト値に維持しました。

-XX:G1HeapRegionSize=n, XX:MaxGCPauseMillis=m, -XX:ParallelGCThreads=n, 
-XX:ConcGCThreads=n apart from -Xms and -Xmx

これらのパラメーターを微調整する場合は、この Oracle の記事をご覧ください。

主な観察結果:

  1. CMSの高低とは異なり、メモリ使用量はG1GCと一貫しています
  2. 最大GC一時停止時間はCMSと比較して短い
  3. ガベージコレクションに費やされる時間は、CMSと比較してG1GCで少し長くなります。
  4. 主要なコレクションの数は、CMSと比較してほとんど無視できます
  5. マイナーコレクションの数は、CMSと比較して上位にあります

それでも、Max GCの一時停止時間がCMSの場合よりも短いことを嬉しく思います。最大GC一時停止時間を1.5秒に設定しましたが、この値はまだ超えていません。

関連するSEの質問:

Java 7(JDK 7)ガベージコレクションとG1に関するドキュメント

4
Ravindra babu

CMSは、古いオブジェクトを蓄積せずに実行している場合でも、パフォーマンスが徐々に低下する可能性があります。これは、G1が回避するはずのメモリの断片化のためです。

有料サポートでのみ利用可能なG1の神話は、まさに神話です。 Sunと現在のOracleは、JDKページでこれを明確にしました。

4
Ted Dunning

G1 GCはより適切に動作するはずです。ただし、-XX:MaxGCPauseMillisの設定が強すぎると、ガベージの収集が遅すぎます。それが、David Leppikの例でフルGCがトリガーされた理由です。

4
hypheng

私は最近、Twicsyの一部を128GB RAMの新しいサーバーに移行し、1.7を使用することを決めました。1.6で使用したのと同じメモリ設定をすべて使用し始めました。 500MBのヒープから最大15GBまでのさまざまなものがあり、現在は40GBの新しいもの)、それはまったくうまくいきませんでした。1.7は1.6よりも多くのヒープを使用しているようで、最初の数件で多くの問題を経験しました幸運なことに、多くのプロセスでRAMを使用して、RAMを処理しましたが、まだ問題がありました。数ギガバイトの最大ヒープであっても、16mの非常に小さな最小ヒープサイズを使用し、インクリメンタルGCをオンにすることでした。これにより、一時停止が最小に保たれます。ヒープで平均して使用する予定のサイズに調整し、非常にうまく機能しました。インクリメンタルGCをオンのままにしますが、試してみます。物事は非常に高速に実行されているようです。だから、物語の教訓は、あなたの記憶設定が1.6から1.7に完全に翻訳されることを期待していないと思います。

3
Chris Seline

G1を使用すると、アプリケーションのアジャイル性が大幅に向上します。アプリケーションの遅延が発生します。アプリケーションに「ソフトリアルタイム」という名前を付けることができます。これは、2種類のGC実行(小さなマイナー実行とTenured Genでの大きな実行)を同じサイズの小さな実行に置き換えることによって行われます。

詳細については、以下を参照してください。 http://geekroom.de/Java/java-expertise-g1-fur-Java-7/

2
Daniel

私はG1GCをJava 8およびGroovy(およびJava 8)で使用しています。さまざまな種類のワークロードを行っていますが、G1GCは次のように機能します。

  • メモリ使用量が非常に少ない。デフォルトと比較して500MBではなく100MB Java設定

  • 応答時間は一貫しており、非常に短い

  • 最悪のシナリオ(チューニングなし、シングルスレッドアプリケーション)でG1GCを使用すると、デフォルト設定とG1GC間のパフォーマンスは20%遅くなります。良好な応答時間と低いメモリ使用量をあまり考慮していません。

  • マルチスレッドのTomcatから実行する場合、全体的なパフォーマンスは30%向上し、メモリ使用量ははるかに少なくなり、応答時間ははるかに短くなります。

したがって、全体として、実際にさまざまなワークロードを使用する場合、G1GCは、マルチスレッドアプリケーションの場合はJava 8のコレクターであり、シングルスレッドの場合でもいくつかの利点があります。

1
Andrew

小規模および大規模なヒープのためにJavaで作業していますが、制約が他よりも厳しい場合があるため、GCとFull GCの質問が毎日表示されます:特定の環境では、0.1秒のスカベンジャーGCまたはフルGC、kill単純に機能し、きめ細かな構成と機能を持つことが重要です(CMS、iCMS、その他...ターゲットは、ほぼリアルタイムの処理で可能な限り最高の応答時間を得るためです(ここで、リアルタイムの処理は多くの場合25 msです) 、したがって、基本的に、GC人間工学とヒューリスティックの改善は大歓迎です!

1
Fuby

ホットスポットのようなJVMでの浮動小数点計算にJava8 w/G1GCを使用することは推奨されていません。アプリケーションの整合性と正確性にとって危険です。

https://bugs.openjdk.Java.net/browse/JDK-8148175

JDK-8165766

JDK-8186112

0
user7796409