Go 1.6がガベージコレクションを高速化

Go 1.5が世に出てからそれほど経たないにも関わらず,Goチームはすでに,停止時間を削減した,新しい並列型ガベージコレクタへの改良作業に着手している。Goの適用範囲を,新たなアプリケーション分野に拡張するためだ - Googleの技術者であるAustin ClementsRick Hudson両氏はこのように述べている

Go 1.5は,STW(Stop the World)形式の旧GCに代わる新しいガベージコレクタ(GC)を装備することで,レイテンシ問題を解決した最初のリリースである。新GCでは,高負荷時の50msのタイムスロットに対するアクティビティを10ms以下に下げることで,一般的な状況下でのGoプログラム実行を数パーセント高速化している。より厳しい状況下では,停止時間が300msから4msに削減される場合もある

Go 1.6での目標はGCの安定化と,さまざまな面での改良だ。

  • ステートコーディネーション: Go 1.5のGCの大きなボトルネックは,Go 1.4から引き継いだ集中型のGCコーディネータにある。単一のgoroutine(スレッド)である上に,さらにワーカgoroutineに処理のディスパッチが行われているのだ。これを解決する方法のひとつが,集中型コーディネータの非集中型のステートマシンへの置き換えである。これに伴って,複雑化のためパフォーマンス悪化の原因となっていたマーク完了バリア(mark completion barrier)の再設計が可能になる,とClements, Hudson両氏は述べている。

  • クレジットシステム: Go 1.5では2つの部分でクレジットシステムを使用している。ひとつは,GCサイクル終了から次のヒープトリガまでにスイープが完了することを保証するためであり,もうひとつは,ヒープトリガからそれに続くヒープ目標達成までにスキャンが完了することを保証するためである。クレジットシステムを改善する方法のひとつとして,アロケーションの負債を次のGCサイクルに持ち越さないよう,常に“収支を黒字にする”方法が提案されている。

  • マーク終了: マーク終了フェーズは,両氏によると,Go 1.5での停止時間の最大要因である。ここでの目標は,Go 1.5がすでに多くのケースで達成している,10msというしきい値の範囲内で,大部分のアプリケーションを実行できるようにすることだ。この目的のために必要な変更はいずれも容易か,やや複雑という範疇に入るものだ。例えば,マーク終了フェーズでのファイナライザスキャンから同時スキャンに移行することで,ヒープ1GBあたり1ms程度の短縮が期待できる。それ以外の部分では,大規模なヒープのマーク終了フェーズの大半を占める高価なカウントループを削除する方法がある。

  • スイープとスカベンジ(Scavange): 両氏によると,スイーパ(Sweeper)は一部のプログラムで非常に時間を要している領域だが,いくつかの配慮をすることで,相当なパフォーマンス改善が期待できる。極端な対応策は,スイーパそのものを完全に排除してしまうことだ。そこまで過激ではないアプローチとしては,物理的なページサイズに関わらず,GCフェーズの最終段階において大規模オブジェクトを積極的に解放した上で,すべてのシステム上のスカベンジャを有効にする,という方がもある。

上記は計画されている変更の概要のみを示したもので,詳細は元の文書で確認することができる。各変更の理論的根拠と推奨アプローチを記載したGitHubイシューへのリンクも提供している。