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


91

Java 7はデフォルトで新しいG1ガベージコレクションを使用するので、Javaは、「破壊的な」GC一時停止時間を想定せずに、桁違いに大きなヒープを処理できるようになりますか?実際にG1を実際に実装した人はいますか?あなたの経験は何でしたか?

公平を期すために、私が本当に長いGCの一時停止を目にしたのは、ワークステーションの場合よりもはるかに大きなヒープでした。私の質問を明確にするために; G1は数百GBのヒープへのゲートウェイを開きますか?TB?


15
より具体的に言い換えることもできますが、これは恐ろしい質問ではありません。閉会に投票するとき、人々が「質問ではない」よりも自分自身をよく説明しなければならなかったことを本当に望みます。
ビルK

私は決議に投票しませんでしたが、OPが現在のGCで彼の不満を詳しく説明するより客観的な仕事をしたかったのに。また、「Java」は言語であり、実装について語っています。特に、「本番環境でのG1の実装」が何を意味するのかはわかりません。特に、残りの質問については、将来の時制についてはわかりません。Java 7になる予定の場合、実稼働では誰も使用していません。
Pascal Cuoq

6
@Pascal G1は、JDK 6アップデート14以降、JDKで利用できる実験的な機能です。「本番環境でG1を実装する」ことにより、彼は実際にそれを使用するつもりだったと思うので、理解するのはそれほど難しくありません。また、G1はJavaではなくJDK 7の一部であることに同意しますが、GoogleでJava 7を検索すると、最初の結果としてJDK 7ホームページが返され、多くの場合、両方の用語は同じ意味で使用されます。@Benju現在のJDKでG1を使用して得られた結果は実験的なものであるため、信頼できません。多くの点で、これから公式リリースに変更される可能性があります。
teto

2
アップデート1、2、3を含むJDK 7はデフォルトでG1 gcを使用しないようです。jinfo -flag UseG1GC pid
George

回答:


34

G1のポイントは、最大休止時間の目標を指定する機能まで、休止時間を短くすることです。

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

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

編集:

読み直すと、私は毎日Javaを使用していることに気付きました。Eclipse、Azureus、そして私が開発したアプリで、一時停止を見てから長い間です。重要な一時停止ではありませんが、一時停止を意味します。

Windowsエクスプローラーを右クリックしたとき、または(ときどき)特定のUSBハードウェアを接続したときにJavaがまったく表示されないなど、一時停止が発生しました。

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


私はどちらか故意か偶然超並列ごみ作成コードでそれらを引き起こしてきたとき、私はGCの一時停止見てきただけの時間がある..... -同意
mikera

28
はい。GCは、大きなヒープ(> 16GB)を処理し始めたとき、特に大きな世代の世代でまだ非常に大きな問題です。
錬金術師、

2
@ the-alchemistすごい、あなたのコメントを何度か見ましたが、16 GBと言ったのはとても印象的でした。これにより大きな遅延が発生する可能性があることは間違いありませんが、すべてのスワッピングを無効にしたことを確認したいと思います。大容量のメモリシステムでは、任意の(GCは非常にスワップ非友好的であるため)は、Javaの交換は絶対にあなたのシステムを殺すでしょう。あなたはすでにこれを行っていると思いますが、私はそれについて言及したかっただけです-それはそのような大きな違いをもたらすからです。これほど多くのRAMが搭載されたPCを見たことがありません。32g?
Bill K

8
はい、GCはTP99.9(およびそれ以上)の制限を改善することを非常に困難にしているため、サービスにとって問題があります。具体的には、「旧世代」のGCは、JVM(およびサービス)を数秒間フリーズすることを除いて、すべてがデストラップになる可能性があります。また、通常は1桁(または2桁)のミリ秒単位で要求を処理するサービスの場合、これには問題があります。価値があるのは、これはAmazonのSimple Queueサービスで使用されるバックエンドストレージの実際的な問題でした(AWSの内部であるため、大量の詳細情報には入りません)。
StaxMan 2010

21
GCの厄介な点は、Azulが数年前に発明した巧妙なGCアルゴリズム(Azul C4)を発明したことです。しかし、これは誰にもわからず、オペレーティングシステムによるサポートが必要なため、Javaのメジャーバージョンにはすぐには実装されません。そして、オペレーティングシステムベンダーは、人々がアルゴリズムについて知って、オペレーティングシステムベンダーに圧力をかけるまで何もしません。参照azulsystems.com/zing/pgcmanagedruntime.org
ハンス・ペーター・ストー

58

私は重いアプリケーションでそれをテストしてきました:ヒープに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は何も購入しません。


14

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

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

これは、G1が多くの支援を期待されていた1つの分野です。ストレージとメッセージディスパッチのためのクラウドサービスを提供する大企業で働いていました。また、CMSは、ほとんどの場合、並行品種よりもうまく機能しましたが、これらのメルトダウンがあったため、使用できませんでした。したがって、約1時間は物事は良かった。そして、ものはファンにぶつかりました...そしてサービスはクラスターに基づいていたので、1つのノードが問題を起こしたとき、他のノードが一般的に続きました(GCによって引き起こされたタイムアウトは他のノードがノードがクラッシュしたと信じ、再ルーティングにつながるため)。

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


13

AzulのCTOであるGil Teneは、ガベージコレクションに関連する問題の概要と、Javaガベージコレクションの理解とさまざまな解決策のレビューを提供しています。この記事には、http:// www.infoq.com/articles/azul_gc_in_detail

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

CMSとG1の問題は、ある時点でJavaヒープメモリを圧縮する必要があり、これらのガベージコレクターの両方が圧縮を実行するためにstop-the-world / STW(つまりアプリケーションを一時停止)することです。したがって、CMSとG1はSTWポーズを押し出すことができますが、それらをなくすことはできません。ただし、AzulのC4はSTWの一時停止を完全に排除しているため、巨大なヒープサイズでもZingのGCの一時停止が非常に低くなっています。

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


3
AzulのC4があなたの言ったことをどのように達成したのか、なぜSunやOracleができないのかと思います。大きな秘密はありますか、それともトレードオフのようなものですか?
ジョージ

5
AzulのC4は、Azulのハードウェアコンピューティングアプライアンス(エンタープライズJavaアプリを実行するために構築された専用プロセッサーを使用)に起源を持つ非常にユニークなテクノロジーを備え、Linuxを実行する通常のx86サーバーで実行するように進化しました。他のすべてのエンタープライズクラスのガベージコレクター(OracleまたはIBMのいずれかから)は、ある時点で世界一周の一時停止を行う必要があります。気になる方は、C4コレクターの発明者たちが、それがどのように機能するかについての論文を公開しました:dl.acm.org/citation.cfm?id=1064988
スコットセラーズ

スコット、私はここでblog.mikemccandless.com/2012/07/…を読みました。Azulは、JVMの使用にメモリを事前に割り当てるカーネルモジュールを出荷しています。これは本当ではないですか?trueの場合、カーネルの変更の大部分ではなく、変更です。
Dan Pritts 2013

4
ジョージ、2つの言葉:保護された特許。ダン、あなたがZingを購入するとき、あなたが支払うものの一部は彼らのサポート人にあなたのアプリケーションのためにそれを調整させることです-そしてそれは全体的なシステムメモリ使用量の割り当てを含みます。カーネルモジュール自体は、ガベージコレクションされているメモリブロックへの書き込みを防ぎます。それが「一時停止」する秘密のソースです。スレッドは、それらのブロックの1つに書き込もうとした場合にのみ一時停止し、その後、そのブロックを圧縮するのに十分な時間だけ停止します。
David Leppik 2014年

13

ほぼ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

5
Java 8では、-XX:+ UseCompressedOopsまたは-XX:+ DoEscapeAnalysisを設定する必要はありません。ブースはデフォルトでオンになっています。参照:docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
Mirko Ebert

8

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


「G1の本番環境での使用は、Javaサポート契約が購入されている場合にのみ許可されることに注意してください。」groups.google.com/forum/#!topic/javaposse/Vm0a4H-QY54、それは神話かどうか?
Christophe Roussy

1
@ChristopheRoussyこれが本当であるかどうかはわかりません(または、確かにこれが本当だったという証拠があります)。これは-XX:+ UnlockCommercialFeaturesを必要としないため、G1はライセンスを必要としないと思います。
Peter Lawrey 2016


5

最近引っ越しました

JDK 1.7.45を搭載したサーバーで4Gヒープと8コアプロセッサを搭載したCMSから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の質問:

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


4

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

有償サポートでのみ利用可能なG1に関する神話は、それだけです。SunとOracleは、これをJDKページで明確にしました。


4

G1 GCはよりよく機能するはずです。ただし、-XX:MaxGCPauseMillisの設定が厳しすぎると、ガベージの収集が遅すぎます。そのため、David Leppikの例ではフルGCがトリガーされました。


4

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

テスト結果(全部で26件)はこちら

それが役に立てば幸い。


3

最近、Twicsyの一部を128GB RAMの新しいサーバーに移行し、1.7を使用することにしました。私は1.6で使用したものと同じメモリ設定をすべて使用し始めました(500MBのヒープから15GBまでのさまざまな処理を実行しているいくつかのインスタンスがあり、現在は40GBの新しいものを使用しています)。 。1.7は1.6よりも多くのヒープを使用しているようで、最初の数日間で多くの問題が発生しました。幸運なことに、処理できるRAMがたくさんあり、ほとんどのプロセスでRAMを増やしましたが、それでもいくつかの問題がありました。私の通常のMOでは、最大ヒープが数ギガバイトであっても、最小ヒープサイズとして16mを使用し、インクリメンタルGCをオンにしていました。これにより、一時停止が最小限に抑えられました。しかし、それは今は機能しません。そして、最小サイズを、ヒープで平均して使用することを期待していたものまで増やす必要がありました。そしてそれは非常にうまくいきました。私はまだインクリメンタルGCをオンにしていますが、それなしで試します。今は何も停止せず、物事は非常に高速で実行されているようです。したがって、この話の教訓は、メモリ設定が1.6から1.7に完全に変換されることを期待しないことです。


2

G1を使用すると、アプリケーションの俊敏性が大幅に向上します。アプリケーションのレイテンシが高くなるため、アプリケーションに「ソフトリアルタイム」という名前を付けることができます。これは、2種類のGC実行(小さなマイナーランとTenured Genで1つのビッグラン)を同じサイズの小さいものに置き換えることで行われます。

詳細はこちらをご覧くださいhttp : //geekroom.de/java/java-expertise-g1-fur-java-7/


1

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


1

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

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

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

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

  • マルチスレッドのTomcatから実行すると、全体的なパフォーマンスが30%向上し、メモリ使用量が大幅に減少し、応答時間も大幅に短縮されます。

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.