あなたは、CMS GCを知りません

G1が出てきた前に、CMSは間違いなく、標準的なOLTPシステムです。でもG1は、数年出てきたJVMインスタンスの本番環境のロットまたはParNew + CMSの組み合わせを使用します。でもそのように広く使用されてしかし、多くの学生がまだある、それは深い誤解があります。本論文では、いくつかの概念を修正するために、CMSの古典的な組み合わせ、いくつかのガベージコレクションモード+トリガーの下ParNewに焦点を当てています。

その背景

より多くの人々は唯一のbackgroudのCMSを知らなくても、CMSを知っているかもしれません。実際には、我々はCMSについて話している、つまり、それは、CMSに5つの段階が含まれている背景CMSは、以下に示すように、:

あなたは、CMS GCを知りません

説明

  • 初期マークフェーズはシリアルで、これはJDK7の動作です。JDK8のデフォルトの並列した後、パラメータができます-XX:+CMSParallelInitialMarkEnabled制御します。

  • チャートから、CMSは、2つのフェーズが完全にSTW(世界を停止します)、その初期マークと最終マーク(再マーク)があります。

  • CMSが呼び出されるように、他のステージは、同時ですConcurrent Mark&Sweepが、私はまた、ほとんどの場合、それはCMSで最も適切であるフロントを追加する必要があると思うMostly Concurrent Mark and Sweep Garbage Collector、それは完全に同時可能にする方法がありませんでしたので、。

だけでなく、CMSは、G1で、ZGCのJDK11は完全に同時ではありません。私はすべての現在のGCのために、唯一のC四アズールが完全に同時であることを理解しています。

なぜそこにある背景画像は?:我々は、すべてのCMS設定ガベージコレクション、その後、2つの重要なパラメータがあることを知って-XX:CMSInitiatingOccupancyFraction = 75 -XX:+ UseCMSInitiatingOccupancyOnly旧地区で唯一の2つのパラメータはメモリのわずか75%を占めていることを意味し、トリガがCMSを起動しているがこれが唯一のトリガーCMS GC条件の満足度であることに注意してください。実際のトリガーCMS GCは、バックグラウンドスキャンスレッドが決定したときも。= 5000 CMSWaitDuration、あなたはjstackログによって、このスレッドを見ることができます加えて:CMSThreadのデフォルト2秒CMSをトリガするかどうかを決定するためにスキャン時間は、このパラメータは、-XXとして、このスキャンの時間間隔を変更することができます。

"Concurrent Mark-Sweep GC Thread" os_prio=2 tid=0x000000001870f800 nid=0x0f4 waiting on condition

Foregroud

用語は、最初の神は愚か言うのを聞きました。もちろん、神は名詞から製造だけで、自分の愚かではない、この用語は、OpenJDKのソース参照から来ていますconcurrentMarkSweepGeneration.cpp

void CMSCollector::collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause) {
    case Resizing: {
        // nothing to be done in this state. 即这个阶段啥都没做
        _collectorState = Resetting;
        break;
    }  
    case Precleaning:
        // 预清理啥都没干
    case AbortablePreclean:
        // Elide(省略,取消的意思,相当于这个阶段也啥都没做) the preclean phase
        _collectorState = FinalMarking;
        break;
    default:
        ShouldNotReachHere();
}

ソースは、より多くの、私はすべての投稿、興味のある学生は、ソースコードビューをダウンロードすることができません。

シーンそれは、このようなメモリを割り当てる事業スレッド要求として、起こりますが、メモリが十分ではありませんので、CMS GCをトリガーすることができ、このプロセスは行くために次に続けるためには、メモリ割り当ての成功ビジネスのスレッドを待たなければならないので、全体のプロセスはSTWなければならないので、この全体のプロセスは、CMS GC STWの一種であるが、効率を向上させるためには、それだけでいくつかの段階を取って、各段階で行くことはありません、我々は上記のソースで見ることができ、これらの保存されたステージは、並列の段階である:前洗浄、AbortablePreclean、サイズ変更。しかし、あなたはこのCMS GCの同様のフォアグラウンド、その後、全体のビジネスプロセスのスレッドが利用できないを取るとにかく場合、効率は大きなものに影響を与えます。

実際の前景コレクションモードは、FullGCを何が起こったのか、この比較の分析により、それがFullGC CMSその背景を示しているモードのギャップは依然として非常に大きい集めます。

FullGCをトリガした場合、それはParNew + CMSは、最悪のシナリオを組み合わせています。同時モデルを扱うことができないこの時間があり、全体のプロセスはシングルスレッドであるため、完全にSTW、それも圧縮できスタック(MSCの段落の説明の後ろに山を圧縮するかどうか)、本当に悪いことはできません!場合は大企業よりも、この時間を想像して、サービスによりFullGC完全に数秒間一時停止やユーザーエクスペリエンスへの影響のさえ10秒で結果がはるかに大きいです。

また、G1はまた、FullGCジャンクレベルの存在である、ロットG1のように考えていません。

G1のガベージコレクタは、フルコレクションを回避するように設計されていますが、同時コレクションは秋に十分な速さのメモリを再利用することができないときのバックフルGCが発生します。現在の実装  G1の完全なGCは、シングルスレッドマークスイープコンパクトアルゴリズムを使用します

元から:http://openjdk.java.net/jeps/307

MSC

MSCの略マークスイープ・コンパクト、すなわちマーク-クリーンアップ-圧縮、MSCアルゴリズムで、コンパクトに注意してください、つまり、それは非常に重要であるヒープを圧縮します。

これは、特定の状況で使用されるCMSを前景ガベージコレクションアルゴリズムです。それはMSCを使用して圧縮されるときについては、まだ、ソースコードを見concurrentMarkSweepGeneration.cppに:

//a method used by foreground collection to determine what type of collection 
//(compacting or not, continuing or fresh)it should do.
void CMSCollector::decide_foreground_collection_type(){
  ... ... 
  *should_compact =
    UseCMSCompactAtFullCollection &&
    ((_full_gcs_since_conc_gc >= CMSFullGCsBeforeCompaction) ||
     GCCause::is_user_requested_gc(gch->gc_cause()) ||
     gch->incremental_collection_will_fail(true /* consult_young */));    
  ... ... 
}

圧縮アルゴリズムあればフォアグラウンドコレクションモードMSCモードで、このソースから見て、その後、-XX:+UseCMSCompactAtFullCollection前提の下での可能な3つがあります。

  1. 最後の実行後にCMS同時GC、実行はパラメータ-XX:CMSFullGCsBeforeCompaction=00がデフォルトである一方、フルGCの数は、指定された0は、それぞれの圧縮後FullGCます。

  2. もちろん会うにSystem.gc()を呼び出します-XX:-DisableExplicitGC

  3. プロモーション保証の失敗は、そのはYoungGC振興次のオブジェクト旧地区を収容するのに十分なスペースを持つことが期待されていません。

どうやって?

断片化の問題は、ほとんどの人が使用するアルゴリズムは、CMSの場所を批判クリーニングラベル付けされています:マークbackgroudのCMSクリーニングアルゴリズムを使用すると、FullGCを隠されていたメモリの断片化の問題につながることができます長いSTWのを引き起こすことが起こります

FullGCなひどい、それを緩和、または日中それを回避しようと、さえピーク期間が発生する方法がありますか?そこ!私はあなたに不誠実なシェアを与える、私は彼らがこのレシピを入手する前に、どのように何年も前にどこ伝聞を覚えていないが、アリの前にいくつかのビジネスも、このレシピ、処方は、とにかく、確かに便利来るどんなにを使用すると言われています。レシピは簡単です:強制トリガーFullGCは、(パラメータの組み合わせを必要とする最低のピーク営業期間中(午前2,3ポイントがとき例えば、多くの企業が、夜の死者で大陸を選択することができます)-XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0、これら2つのパラメータは、トリガを示し、デフォルトでFullGC圧縮ヒープ)は、ヒープメモリの断片化と圧縮を最適化するために還元 FullGCの確率を(唯一の排除ではなく、減少させることができる)、ピーク期間中に発生します。

さえ知らないFullGCをトリガするために強制的に学生の小さな部分があるかもしれません、私は最後に良いこと、西に仏:

# 没有开启-XX:+DisableExplicitGC的前提下调用System.gc()就会发生FullGC
System.gc();

或者通过jmap命令触发:
# jmap -histo:live pid

概要

慣例により、要約への最後:

  • その背景トリガモード収集モードによって複雑化される通常の状況下でCMS GC、小規模ビジネスへの影響、こんにちは、私はとても良いです。

  • 並行モードを処理できない場合には、それはフォアグラウンドモードに退化し、景気回復のプロセスのスレッドが利用できない、この時間は、FullGCを引き起こしました。

  • 上記次満たすいくつかの条件のMSCは、圧縮アルゴリズムのスタックを使用するかどうかを決定します。

  • CMSFullGCsBeforeCompactionはプロモーション障害の原因となる、原因メモリの断片化の問題に、MSCの圧縮アルゴリズムを使用する前に、FullGCがヒープを圧縮回数の後に決めるあなたにどのくらいの特定の構成が、あまりお勧めしませんが、そうでない場合はヒープ、要するに、これはトレードオフです。

おすすめ

転載: blog.51cto.com/14230003/2437694