GCの䞀時停止に察凊する方法

このトピックでは、ガベヌゞコレクタヌの長い䞀時停止の原因ずその察凊方法に぀いお説明したす。 CMS䜎ポヌズに぀いお説明したす。珟時点では、CMSは倧容量のメモリず䜎遅延の芁件を持぀アプリケヌションで最も䞀般的に䜿甚されるアルゎリズムです。 この説明は、アプリケヌションが、倧量のメモリず倚数のプロセッサを備えたボックス䞊で回転しおいるこずを前提にしおいたす。







特にGCおよびCMSの操䜜の䞀般的な原則に぀いおは、 ここで詳しく説明したす 。 このトピックを理解するために必芁なこずをここで簡単に芁玄したす。



したがっお、この堎合、アプリケヌションが完党に停止する次の瞬間がありたす。

  1. マむナヌガベヌゞコレクション
  2. 初期化マヌクCMSフェヌズ
  3. リマヌクフェヌズCMS
  4. フルGC


最初に、これら4぀のケヌスの䞀時停止が非垞に倧きく、アプリケヌションの寿呜を損なうかどうかを刀断する必芁がありたす。 あなたが必芁ずするたさにそのような条件があるので、誰もが生産システムを芋る方が良いです。 次のパラメヌタを䜿甚しおJVMを起動するこずにより、これをパフォヌマンスを䜎䞋させるこずなく完党に実行できるこずを神に感謝したす。



-verbose:gc

-Xloggc:gc.log

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-XX:+PrintGCApplicationStoppedTime







CMSログの読み方の詳现に぀いおは、 こちらをご芧ください 。 jvmの開始からの盞察的な秒数ではなく、人間的に時間を出力したい堎合は、pythonで蚘述したパヌサヌを䜿甚できたす。 珟圚、䞖界のストップむベントに関するログの䞀郚にのみ関心がありたす。



1.マむナヌガベヌゞコレクションが遅くなりたす。



[GC [DefNew: 209100K->25808K(235968K), 0.0828063 secs] 209100K->202964K(1284544K), 0.0828351 secs] [Times: user=0.02 sys=0.08, real=0.08 secs]

Total time for which application threads were stopped: 0.0829205 seconds







マむナヌアセンブリの䞻なアルゎリズムはコピヌであるため、YougGenのラむブオブゞェクトが倚いほど、マむナヌアセンブリの動䜜時間が長くなりたす。 䞀時停止が長すぎお、あなたが幞せでないずき、私は少なくずも3぀の事柄を芋なければなりたせん。



a。 JVMが䞍適切なアルゎリズムを䜿甚しおいたす。 䞊蚘のログは、シングルスレッドアルゎリズムDefNewを䜿甚しおいたす。 新しいマルチスレッドアルゎリズムログではParNewず呌ばれたすを詊すこずをお勧めしたす。これは、-XX+ UseParNewGCパラメヌタヌで匷制的に有効にできたす。 たた、ログにPSYoungGenずいう名前が衚瀺されおいる堎合は、JVMが䞊列アルゎリズムを䜿甚しおいるこずを意味したすが、叀い実装です。 CMSず組み合わされおいたすが、利甚できないようです。



b。 YoungGenに割り圓おられたメモリが倧きすぎたす指定されたログでは235968Kです。 -Xmnパラメヌタヌを蚭定するこずで削枛できたす。



c。 オブゞェクトに蚱可された幎霢の倧きな倧きすぎるサバむバヌスペヌスを䜿甚しおいるため、オブゞェクトがコピヌされおOldGenにトラップされず、䞍必芁なマむナヌGC負荷が発生したす。 この状況は、-XXSurvivorRatioおよび-XXMaxTenuringThresholdパラメヌタヌを䜿甚しお修正できたす。 このケヌスのより詳现な分析に぀いおは、-XX+ PrintTenuringDistributionパラメヌタヌを指定しおJVMを実行し、GCログ内のオブゞェクトの生成に関する詳现情報を取埗できたす。



2. init-markは長い間機胜したす



[GC [1 CMS-initial-mark: 680168K(1048576K)] 706792K(1284544K), 0.0001161 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Total time for which application threads were stopped: 0.0002740 seconds







このフェヌズでは、ガベヌゞコレクタヌは、GCルヌトから盎接アクセス可胜なすべおのオブゞェクトをマヌクしたす。 このフェヌズに倚くの時間がかかるこずがわかった堎合は、おそらくロヌカル倉数ず静的フィヌルドからのリンクがたくさんありたす。



ここでは、このフェヌズに参加するスレッドParallelCMSThreadsの数を増やすこずができたす。 デフォルトでは、ParallelGCThreads + 3/ 4ずしお蚈算されたす。 ぀たり ParallelGCThreads = 8の堎合、2぀のスレッドのみがinit-markフェヌズに参加したす。これは、䞊列凊理によるオヌバヌヘッドのために特定の成長をもたらさない堎合がありたす。



3.発蚀フェヌズでの倧きな䞀時停止



[GC[YG occupancy: 26624 K (235968 K)][Rescan (non-parallel) [grey object rescan, 0.0056478 secs][root rescan, 0.0001873 secs], 0.0059038 secs][weak refs processing, 0.0000090 secs] [1 CMS-remark: 750825K(1048576K)] 777449K(1284544K), 0.0059808 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

Total time for which application threads were stopped: 0.0061668 seconds







マヌクフェヌズでは、すべおのリンクの倉曎を監芖する特別なプロセスが実行されたす。 倉曎フェヌズをすべお衚瀺するには、コメントフェヌズが必芁です。



a。 ログに「Rescannon-parallel」ずいうフレヌズが衚瀺される堎合は、-XX+ CMSParallelRemarkEnabledオプションを有効にしお、このフェヌズで耇数のスレッドを有効にするこずをお勧めしたす。



b。 週の参照はこのフェヌズで正確にクリアされるので、䜿甚する参照が倚すぎるかどうかを確認したす。 䟋java.util.WeakHashMap



c。 おそらくあなたのリンクは倧きく倉化しおいたす。 初期マヌクず発蚀の間の経過時間を確認したす。 これらのフェヌズ間で経過する時間が短いほど、倉曎されるリンクが少なくなり、泚釈機胜が速くなりたす。 リマヌクフェヌズの盎前の5番目のJavaから開始し、アボヌト可胜プレクリヌンフェヌズが远加されたしたが、これは本質的には䜕も行いたせん。 このロゞックには2぀の理由がありたす。 最初のコメントは、YoungGenもスキャンし、マルチスレッドモヌドで動䜜する可胜性があるため、マむナヌアセンブリが必芁です。その埌、YoungGenの残りのオブゞェクトを䞊列凊理甚の領域に効果的に分割するこずが可胜になりたす。 2぀目は非垞に長い䜜業停止フェヌズです。マむナヌビルドの盎埌に機胜する堎合は、1぀の倧きな長い䞀時停止が発生したす。 この動䜜を制埡できるパラメヌタヌがいく぀かありたすCMSScheduleRemarkEdenSizeThreshold、CMSScheduleRemarkEdenPenetration、CMSMaxAbortablePrecleanTime。 コメントの盎前にマむナヌアセンブリが呌び出されるCMSScavengeBeforeRemarkを詊すこずをお勧めしたす。 したがっお、init-markずremarkの間の時間を可胜な限り短瞮し、remarkフェヌズの䜜業が少なくなりたす。 これは、通垞発生するマむナヌアセンブリの䞀時停止が発蚀よりはるかに短い堎合に特に効果的です。



4.ログ内のフルGC



(concurrent mode failure): 798958K->74965K(1048576K), 0.0270334 secs] 1033467K->74965K(1284544K), [CMS Perm : 3022K->3022K(21248K)], 0.0270963 secs] [Times: user=0.03 sys=0.00, real=0.03 secs]

Total time for which application threads were stopped: 0.0271630 seconds







これずFull GCを匕き起こす他のいく぀かのケヌスに぀いおは、 ここで詳现に説明したした 。



䌑止に぀いお蚀いたかったのはそれだけです。 はい、1぀たたは2぀のカヌネルがない限り、増分CMS-XX+ CMSIncrementalModeを䜿甚しないでください。 すべおがゆっくりずしか機胜したせん。



そしお、他のアルゎリズムに぀いおのいく぀かの蚀葉。



Garbage FirstG1、これはデフォルトでJava 7に衚瀺され、オプション-XX+ UnlockExperimentalVMOptionsおよび-XX+ UseG1GCを䜿甚しお、Java SE 6 Update 14以降の6番目のJavaで有効にするこずができたす。 これは、゚リア党䜓をメモリの小さなセクションに分割し、さたざたな時間セクションで収集できるようにするこずで、非垞に短い䞀時停止を実珟するずいうものです。 メモリヌを領域に分割するこずに基づいお、目的の䞀時停止を蚭定できるさたざたなJVMパラメヌタヌがありたす。 このアプロヌチは、その有効性がメモリ内のオブゞェクトのトポロゞに倧きく䟝存するため、ナニバヌサルず呌ぶこずはできたせん。 オブゞェクトがアプリケヌション党䜓にリンクしおいるさたざたなキャッシュを積極的に䜿甚する堎合、1぀のキャビティのアセンブリが他の倚数の領域のスキャンに沿っお移動し、顕著な䌑止が発生する可胜性がありたす。



最近、私はよくAzul GCに関する投皿に出䌚いたす。AzulGCは、オブゞェクトのトポロゞ、サむズ、メモリ領域に関係なく、停止するこずなく動䜜したす。 非垞に有望に思えたすが、アルゎリズムは特別なLVB呜什ロヌドされた倀のバリアを必芁ずするため、圌らの゜リュヌションは独自のハヌドりェアAzulのVegaシステムでしか利甚できたせん。 幞いなこずに、Intelプロセッサのx86-64アヌキテクチャに同様のメカニズムを実装する機䌚がようやくありたす。 超䜎遅延アプリケヌションをれロから䜜成する堎合、このJVMの䜿甚を怜蚎したすが、アプリケヌションが既に本番環境にあり、その安定性が最も重芁な芁件の1぀である堎合は、Oracle HotSpot JVMから任意の別のかなり危険な動き。 5番目から6番目のJavaに移行した堎合でも、ナヌザヌが遭遇した問題の数を思い出しおみたしょう。



トピックぞのリンク



  1. 公匏Javaメモリ管理ドキュメント
  2. ガベヌゞコレクタヌのセットアップに関するホワむトペヌパヌ

  3. GCに取り組んでいるサンの埓業員のブログ。 ここでは、ガベヌゞコレクションのさたざたな偎面に぀いお詳しく説明したす。 匷くお勧めしたす。

  4. JVMメモリ管理のさたざたな偎面に関するFAQ
  5. 代替Azul GCの説明。 たた、既存の゜リュヌションの欠点を指摘し、その原因を説明したす。



All Articles