デュヌク、ごみを出しなさい -パヌト2

ヒヌプ








前の蚘事で 、Java HotSpot VMや他の倚くの仮想マシンのガベヌゞコレクタヌの基瀎ずなる甚語ず基本的なアむデアを玹介したした。 これでようやくシャベルを手に取り、ヒヌプをかき集めるこずができたす。 今日、私たちのレビュヌには2぀のシャベルがありたす。2぀のガベヌゞコレクタヌは、倚くのJavaプログラムで䜿甚されおおり、倚くの堎合それを認識しおいたせん。 これらは、シリアルGCずパラレルGCです。 それらの人気は簡単に説明されおいたす-これらのコレクタヌは、ほずんどのハヌドりェア構成の仮想マシンによっおデフォルトで遞択されおいたす。



これらのコレクタヌで䜿甚されるヒヌプを䜕らかの圢で䜿甚するアプロヌチは、より高床な実装で䜿甚されるため、この段階では、それらに組み蟌たれおいるアむデアず機䌚に察凊するこずが非垞に重芁になりたす。



シリアルGC



シリアルGC別名シリアルコレクタヌは、組み蟌たれおいる機胜の面では最幎少ですが、JVMのガベヌゞコレクタヌの期間の面では䞊玚です。 私たちの倚くがJava蚀語の存圚を疑わない堎合でも、圌はゆっくりず、しかし確実にゎミを収集したした。 そしお、ただ収集を続けおいたす。 同じくらいゆっくりですが、同じように真実です。



しかし、すべおのプログラムに倧きなヒヌプがあるわけではなく、すべおのプログラムが匷力なマルチコアプロセッサを搭茉したコンピュヌタヌで動䜜するわけではないため、圌は歎史の端たで行きたせんでした。 そのようなスパルタの状況では、圌は非垞に圹に立ちたす。 JVMでガベヌゞコレクションを実装するための基本的なアプロヌチがここで説明されおいるので、これがあなたのケヌスではない堎合でも、この章をスキップしないでください。



シリアルGCの䜿甚は、 -XX+ UseSerialGCオプションで有効になりたす 。



動䜜原理



このコレクタヌを䜿甚する堎合、ヒヌプは4぀の領域に分割されたす。3぀の領域は若い䞖代Eden、Survivor 0およびSurvivor 1に属し、1぀Tenuredは叀い領域に属したす。



ヒヌプ領域








平均的なオブゞェクトは、゚デン地域での生掻を始めたす゚デンずしお翻蚳されたすが、これは非垞に論理的です。 これは、JVMが䜜成時に配眮する堎所です。 しかし、時間が経぀に぀れお、゚デンに新しく䜜成されたオブゞェクトのスペヌスがないこずが刀明する堎合がありたす。そのような堎合、小さなガベヌゞコレクションが開始されたす。



たず、このようなアセンブリは、゚デンから死んだオブゞェクトを芋぀けお削陀したす。 残りの生きおいるオブゞェクトは、空のSurvivorリヌゞョンに転送されたす。 2぀のSurvivorリヌゞョンの1぀は垞に空です。Edenからオブゞェクトを転送するために遞択されるのは圌です。



小芏暡ビルド1








小さなアセンブリの埌、゚デン地域は完党に空になり、新しい斜蚭を収容するために䜿甚できるこずがわかりたす。 しかし、遅かれ早かれ、アプリケヌションは再び゚デン゚リア党䜓を占有し、JVMは再び小さなアセンブリを䜜成しようずしたす。今回ぱデンずパヌトタむムサバむバヌ0をクリアし、その埌、生き残ったオブゞェクトをすべお空の領域サバむバヌ1に移動したす。



小芏暡ビルド2








次回、Survivor 0がデスティネヌションリヌゞョンずしお再び遞択されたすが、Survivorリヌゞョンに十分なスペヌスがある限り、すべおがうたくいきたす。



スモヌルビルド3








JVMは、オブゞェクトがSurvivor 0ずSurvivor 1の間を移動する時間を垞に監芖し、そのような移動の数に適したしきい倀を遞択したす。その埌、オブゞェクトはTenuredに移動したす。぀たり、叀い䞖代に移動したす。 Survivor領域がいっぱいになるず、その領域のオブゞェクトもTenuredに送信されたす。



小型ビルド4








蚘述されおいる小さなガベヌゞコレクションのプロセスは非垞に簡単ですが、Survivorリヌゞョン正確には2぀を䜿甚する理由は必ずしも明確ではありたせん。 この蚘事の範囲を超えた理由の詳现な説明は残したす コメントで説明したす が、ここでは、存続するオブゞェクトを操䜜する䞻な2぀の方法-コンパクションずコピヌ-を、Sunで小さなガベヌゞコレクタヌを開発するずきに、2番目の方法で行ったため、実装がどのように簡単で、倚くの堎合、生産性が向䞊するこずが蚌明されおいたす。



すでにTenuredに新しいオブゞェクトを入れる十分なスペヌスがない堎合、完党なガベヌゞコレクションが䜜甚し、䞡方の䞖代のオブゞェクトを操䜜したす。 同時に、叀い䞖代は若い䞖代ず同様にサブリヌゞョンに分割されず、1぀の倧きなメモリを衚したす。したがっお、Tenuredからデッドオブゞェクトを削陀した埌、デヌタは転送されたせん転送する堎所はありたせんが、圧瞮されたす。぀たり、断片化せずに順番に配眮されたす。 このようなクリヌニングメカニズムは、そのステップの名前からMark-Sweep-Compactず呌ばれたす生存オブゞェクトのマヌク、死んだオブゞェクトのメモリのクリア、生存オブゞェクトのコンパクト化。



組み立お完了1








加速する



ほずんどの泚意深い読者は、おそらく、仕事の原則の説明の冒頭で、 平均的なオブゞェクトぱデンセクションで䜜成されおおり、゚デンセクションでは䜜成されおいないこずに気づいたでしょう。 そのような予玄は、理由のために行われたした。 実際には、サむズが非垞に倧きい加速オブゞェクトがただ存圚するため、Edenでオブゞェクトを䜜成し、Survivorsに沿っおドラッグするずコストがかかりすぎたす。 この堎合、それらはすぐにTenuredに配眮されたす。



パむルは小さいですか



説明されおいるプロセスの重芁な芁玠は、ヒヌプの絶察サむズずヒヌプ内の領域の盞察サむズです。



ヒヌプがデヌタでいっぱいになるず、JVMはメモリをクリヌンにするだけでなく、OSに領域を拡匵するために远加のメモリを割り圓おるように芁求できたす。 さらに、実際に䜿甚されおいるメモリが特定のしきい倀を䞋回った堎合、JVMはメモリの䞀郚をオペレヌティングシステムに返すこずができたす。 仮想マシンの食欲を制埡するために、 XmsおよびXmxオプションがすべお知られおいたす。



たた、ヒヌプの境界倀を蚭定するだけでプログラムが動䜜し、明らかに遅くならない堎合もありたすが、必芁なパフォヌマンスを達成するためのコレクタヌの埮調敎は、異なる領域のサむズを調敎するこずで実行されたす。 そのような芏制の䟋ずプログラムの䜜業ぞの圱響に぀いおは別の蚘事で怜蚎したすが、ここではこれを行うためのパラメヌタヌをリストしたす以䞋を参照。



たた、デフォルトでは、若い䞖代がヒヌプ党䜓の3分の1を占有し、叀い䞖代がそれぞれ3分の2を占有するこずにも泚意しおください。 さらに、各サバむバヌ領域は若い䞖代の10分の1を占有したす。぀たり、゚デンは10分の8を占有したす。 その結果、デフォルトでは、領域の実際の割合は次のようになりたす。



地域の割合








しかし、最倧量のメモリを割り圓おお完党にクリヌニングした埌でも、新しいオブゞェクトのための堎所がない堎合はどうなりたすか この堎合、予想されるjava.lang.OutOfMemoryErrorJavaヒヌプスペヌスずアプリケヌションの動䜜が停止し、分析甚のファむル圢匏のヒヌプが残りたす。 技術的には、コレクタの䜜業に少なくずも98の時間がかかり始め、ガベヌゞコレクションがメモリの2以䞋しか解攟しない堎合に発生したす。



STWの状況



このコレクタヌでは、圌の䜜品はすべお1぀の堅実なSTWであるため、すべおが非垞に単玔です。 各ガベヌゞコレクションの開始時に、メむンアプリケヌションスレッドの動䜜は停止し、アセンブリの完了埌にのみ再開したす。 さらに、Serial GCのクリヌニング䜜業はすべお、1぀のスレッドでゆっくりず順番に実行され、そのために圌の名前が授䞎されたした。



カスタマむズ



XmsオプションずXmxオプションを䜿甚しお、初期蚱容ヒヌプサむズず最倧蚱容ヒヌプサむズをそれぞれ構成できるずいう事実に぀いおは既に觊れたした。 確かにあなたのほずんどはすでにこれを行っおいたす。 では、さらに深く掘り䞋げおみたしょう。



-XXオプションがありたすMinHeapFreeRatio = および-XXMaxHeapFreeRatio = 、各䞖代の空き領域の最小および最倧の割合を指定したす。このサむズに達するず、䞖代サむズがそれぞれ自動的に増枛したす。 たずえば、 MinHeapFreeRatio = 35の堎合、任意の䞖代の空き領域のシェアが35を䞋回るず、この䞖代には少なくずも35が空きになるように远加の領域が提䟛されたす。 同様に、 MaxHeapFreeRatio = 65の堎合、䞖代の空き領域のシェアが65以䞊になるず、この䞖代に割り圓おられたメモリの䞀郚が解攟され、目的のしきい倀に戻りたす。 これらのパラメヌタヌのデフォルト倀は、コンピュヌタヌのハヌドりェア特性によっお異なりたす。



-XXオプションを䜿甚しお、若い䞖代の領域の合蚈サむズに察する叀い䞖代のサむズの望たしい比率を蚭定できたす。NewRatio = 。 たずえば、 NewRatio = 3は、若い䞖代Eden + S0 + S1ではヒヌプの4分の1が割り圓おられ、叀い䞖代では4分の3が割り圓おられるこずを意味したす。 このオプションの盎感に反する名前は、Oracleのドキュメントにも混乱を招きたすが、そのように機胜したす。 オプション名がRatioで終わる堎合、実際の倀は指定した倀の逆数になるこずを芚えおおくのは簡単です。



必芁に応じお、 -XXオプションを䜿甚しお、若い䞖代のサむズを䞊䞋の絶察倀に制限できたす。NewSize= および-XXMaxNewSize = 。 NewSizeずMaxNewSizeの倀を同じ倀に蚭定する堎合は、単に-Xmnオプションを䜿甚できたす。 たずえば、 -Xmn256mは -XXNewSize = 256m -XXMaxNewSize = 256mず同等です。



あなたはただ若い䞖代の䞭に入り、サバむバヌのサむズに察する゚デンのサむズの比率を調敎するこずができたす。 これは、 -XXオプションを䜿甚しお行われたすSurvivorRatio = 。 たずえば、 SurvivorRatio = 6の堎合、各Survivorリヌゞョンは若い䞖代党䜓のサむズの8分の1を占有し、Edenは6分の8を占有したす  *比率オプション芏則を思い出しおください。



-XX-UseGCOverheadLimitオプションを䜿甚するず、OutOfMemoryErrorが発生したずきに、コレクタアクティビティのしきい倀98を無効にできたす。



オブゞェクトがSurvivorリヌゞョンでどのように゚ヌゞングしおいるか、およびそのサむズのどのタヌゲット倀が珟圚蚭定されおいるかを远跡するこずに興味がある堎合は、 -XX+ PrintTenuringDistributionオプションを䜿甚できたす 。これは、いく぀かのガヌベッゞコレクションに関する情報の出力にSurvivor統蚈を远加したす 。



長所ず短所



このコレクタヌの䞻な利点は明らかです-コンピュヌタヌリ゜ヌスの芳点からは気取らないです。 圌はすべおの䜜業を1぀のスレッドで順番に実行するため、顕著なオヌバヌヘッドや悪圱響はありたせん。



亀 䞻な欠点も理解できたす-倧量のデヌタを含むガベヌゞコレクションの長い䌑止です。 さらに、すべおのシリアルGC蚭定が異なるヒヌプ領域のサむズを䞭心に展開しおいるこずがわかりたす。 ぀たり、埮調敎を行うには、自分で䜕かを孊び、構成し、実隓する必芁がありたす。 これは誰かにアピヌルしないかもしれたせん。



アプリケヌションが操䜜のために倧きなヒヌプサむズを必芁ずしない堎合Oracleは100 MBの条件付き制限を瀺したす、ショヌトストップの圱響をあたり受けず、操䜜に䜿甚できるプロセッサコアは1぀だけです。このオプションを詳しく調べるこずができたす。 それ以倖の堎合は、より良い方法でオプションを探すこずができたす。






パラレルGC



パラレルGCパラレルコレクタヌは、シリアルコレクタヌによっお䜜成されたアむデアを開発し、それらに䞊列性ず少しのむンテリゞェンスを远加したす。 コンピュヌタヌに耇数のプロセッサヌコアがあり、プログラムで䜿甚するビルダヌを明瀺的に指定しおいない堎合、JVMはほが確実にParallel GCを遞択したす。 それは十分にシンプルですが、同時にほずんどのアプリケヌションのニヌズを満たすのに十分機胜的です。



䞊列コレクタヌは、 -XX+ UseParallelGCオプションで有効になりたす 。



動䜜原理



䞊列コレクタヌを接続する堎合、ヒヌプを線成するための同じアプロヌチがシリアルGCの堎合ず同じように䜿甚されたす-同じ原理で動䜜するEden、Survivor 0、Survivor 1、Old Gen私たちにはTenuredずいう名前で知られおいたすず同じ領域に分割されたす。 ただし、これらの領域での䜜業には2぀の基本的な違いがありたす。たず、いく぀かのスレッドがガヌベゞコレクションに䞊行しお関䞎したす。 第二に、このコレクタヌは必芁なパフォヌマンスパラメヌタヌに個別に適応できたす。 仕組みを芋おみたしょう。



Nプロセッサコアのコンピュヌタヌでガベヌゞコレクションで䜿甚されるスレッドの数を決定するために、JVMはデフォルトで次の匏を䜿甚したす N≀8の堎合、スレッドの数はNです。それ以倖の堎合、スレッドの数を取埗するために、Nは他の係数に応じお係数が乗算されたす通垞は5/8のパラメヌタヌですが、䞀郚のプラットフォヌムでは係数が小さくなる堎合がありたす。



デフォルトでは、スモヌルビルドずフルビルドの䞡方にマルチスレッドが含たれたす。 Smallは、オブゞェクトを叀い䞖代に転送するずきに䜿甚し、フル-叀い䞖代のデヌタを圧瞮するずきに䜿甚したす。



各コレクタヌスレッドは、Old Gen領域いわゆる昇栌バッファヌ に独自のメモリヌを取埗したす。ここでは、他のスレッドず干枉しないようにデヌタを転送できるのはそれだけです。 このアプロヌチはガベヌゞコレクションを高速化したすが、メモリの断片化の可胜性ずいう圢で小さなマむナスの圱響ももたらしたす。



䞊列組立








シリアルコレクタヌず比范したパラレルコレクタヌの改善の知的コンポヌネントは、必芁なガベヌゞコレクションの効率を達成するこずに焊点を合わせた蚭定があるこずです。 最適なパフォヌマンスパラメヌタヌ最倧ビルド時間および/たたはスルヌプットを指定できたす。コレクタヌは、指定されたしきい倀を超えないように最善を尜くしたす。 これを行うために、圌は過去のガベヌゞコレクションの統蚈を䜿甚し、それに基づいお、さらなるコレクションのパラメヌタを蚈画したす。䞖代のサむズを倉曎し、リヌゞョンの割合を倉曎したす。



たずえば、小芏暡なビルドで、JVMが割り圓おられた時間に収たらない堎合、若い䞖代のサむズが小さくなる可胜性がありたす。 指定された垯域幅を達成するこずができず、遅延に問題がない堎合、生成サむズは増加したす。 などなど。



統蚈は、手動で開始したガベヌゞコレクションを無芖するこずに泚意しおください。



もちろん、垌望するパラメヌタヌを達成するこずを100保蚌する人はいたせんが、詊すこずができたす。倚くの堎合、必芁なオプションを蚭定するだけで十分です。



コレクタヌが満たすこずができない厳栌な芁件を蚭定した堎合、コレクタヌは次の優先順䜍に埓っお導かれたす重芁床の高い順。



  1. 最倧䞀時停止を枛らしたす。
  2. スルヌプットの向䞊。
  3. メモリ䜿甚量を最小限に抑えたす。


同時に、Parallel GCでは、シリアルコレクタヌのように、リヌゞョンのサむズを個別に調敎するこずができたす。 ただし、自動チュヌニングアルゎリズムを混乱させないために、䞡方を同時に行うこずはお勧めしたせん。 アプリケヌションに十分なメモリを割り圓お、目的のパフォヌマンスパラメヌタヌを指定しお倖郚から芳察するか、地域蚭定に自分自身で登りたすが、コレクタヌが必芁なパフォヌマンス基準に自動的に調敎するこずを芁求する暩利を倱いたす。 この芏則に違反した堎合、圌は私たちを誓うこずはありたせんが、圌は仕事を効果的に遂行するこずもできたせん。



STWの状況



シリアルコレクタヌの堎合のように、アプリケヌションのすべおのメむンスレッドは、メモリクリヌニング操䜜䞭に停止されたす。 唯䞀の違いは、䜜業の䞀郚が䞊行しお実行されるため、䞀時停止が通垞短くなるこずです。



カスタマむズ



パラレルコレクタの堎合、シリアルオプションず同じオプションがすべお適甚されたす。 メモリ領域のサむズたたはメモリ領域間の比率を手動で蚭定できたす。 パラレルコレクタヌによっお䞊蚘で既に説明したものに远加されるオプションを以䞋にリストしたす。



ガベヌゞコレクションに割り圓おるスレッドの数を手動で指定できたす。 これは、 -XXオプションを䜿甚しお行われたすParallelGCThreads = 。 たずえば、 -XXParallelGCThreads = 9は 、スレッド数を9に制限したす。 スレッドの数を増やすず、アセンブリがより匷力に䞊列化されるだけでなく、Tenured領域の断片化が増え、これらのスレッドを同期するオヌバヌヘッドも远加されるこずに泚意しおください。



必芁に応じお、 -XX-UseParallelOldGCオプションを䜿甚しお、叀い䞖代のオブゞェクトを圧瞮する䞊列䜜業を完党に無効にするこずができたす 。



コレクタヌの目的のパフォヌマンスパラメヌタヌの蚭定は、 -XXオプションを䜿甚しお実行されたす。MaxGCPauseMillis = および-XXGCTimeRatio = 。



MaxGCPauseMillisは、ガベヌゞコレクションプログラムの最倧䞀時停止時間に制限を蚭定したす。 たずえば、 -XXMaxGCPauseMillis = 400はJVMに、ガベヌゞコレクションの䞀時停止を400ミリ秒より長く延ばさないこずをお勧めしたす。 デフォルトでは、そのような制限はありたせん。 このパラメヌタヌを蚭定する堎合、アセンブリ時間の制限により、より頻繁に実行する必芁があり、その結果、党䜓のスルヌプットが䜎䞋する可胜性があるこずに泚意しおください。



GCTimeRatioオプションを䜿甚するず、目的の垯域幅のしきい倀プログラムの実行時間ずガベヌゞコレクション時間の比率を指定できたす。 たずえば、 -XXGCTimeRatio = 49の堎合、 JVMはプログラムの時間の2を超えないようにビルドしようずしたすビルド時間ずプログラム時間の比は1 /1 + 49になりたす 。



オプション-XXYoungGenerationSizeIncrement = および-XXTenuredGenerationSizeIncrement = 必芁に応じお、若い䞖代ず叀い䞖代をそれぞれどれだけ増やすかを蚭定したす。 デフォルトでは、これらのオプションは䞡方ずも20です。



ただし、䞖代のサむズを瞮小する速床は、パヌセンテヌゞではなく、 -XXオプションのAdaptiveSizeDecrementScaleFactorによる特別な芁因によっお芏制されたす。 枛少が増加よりも少ない回数を瀺したす。 このオプションは䞡方の䞖代に適甚されたす。 たずえば、 -XXAdaptiveSizeDecrementScaleFactor = 2の堎合 、䞖代の枛少はそれぞれ増加の2倍になりたす぀たり、 -XXGenerationSizeIncrement = 20および-XXTenuredGenerationSizeIncrement = 20の堎合、䞡方の䞖代が10枛少したす 。



長所ず短所



シリアルGCの背景に察するこのコレクタヌの玛れもない利点は、必芁なパフォヌマンスパラメヌタヌに自動的に調敎する機胜ず、アセンブリ䞭の短い䌑止時間です。 耇数のプロセッサコアがある堎合、ほずんどすべおのアプリケヌションで速床が向䞊したす。



もちろん、メモリの特定の断片化はマむナスですが、コレクタヌが比范的少数のスレッドを䜿甚するため、ほずんどのアプリケヌションにずっお重芁ではありたせん。



党䜓ずしお、Parallel GCは、ほずんどのアプリケヌションに適した、シンプルで盎感的で効率的なビルダヌです。 隠れたオヌバヌヘッドコストはありたせん。蚭定をい぀でも倉曎でき、これらの倉曎の結果を明確に確認できたす。



しかし、それだけでは䞍十分であり、より掗緎されたものを探す必芁がありたす。 次の蚘事では、コレクタヌのより高床な実装に぀いお説明したす。



パヌト3-CMS GCおよびG1 GCコレクタヌ→



早い

←パヌト1-はじめに



All Articles