Goはどのようなガベージコレクションを使用しますか?


111

Goはガベージコレクションされた言語です。

http://golang.org/doc/go_faq.html#garbage_collection

ここでは、マークアンドスイープガベージコレクターであると述べていますが、詳細については掘り下げていません。代わりのものが現在準備中です...しかし、Goがリリースされて以来、この段落はあまり更新されていないようです。

それはまだマークアンドスイープですか?それは保守的ですか、それとも正確ですか。それは世代ですか?


2
2018年7月までのGoガベージコレクターの歴史に関する長い議論については、blog.golang.org / ismmkeynote
Wildcard

回答:


117

Go 1.4以降のガベージコレクターの計画:

  • ハイブリッドストップザワールド/並行コレクター
  • 10ミリ秒の期限で制限された世界一周の部分
  • コンカレントコレクターの実行専用のCPUコア
  • 三色マークアンドスイープアルゴリズム
  • 非世代
  • 非コンパクト
  • 完全に正確
  • プログラムがポインタを移動している場合、わずかなコストが発生します
  • Go 1.3 GCよりもレイテンシは低くなりますが、おそらくスループットも低くなります

Go 1.1に加えてGo 1.3ガベージコレクターの更新:

  • 同時スイープ(休止時間が短くなります)
  • 完全に正確

Go 1.1ガベージコレクター:

  • マークアンドスイープ(並列実装)
  • 非世代
  • 非コンパクト
  • ほぼ正確(スタックフレームを除く)
  • ストップ・ザ・ワールド
  • ビットマップベースの表現
  • プログラムがメモリを割り当てていない場合のゼロコスト(つまり、ポインタのシャッフルはCと同じくらい高速ですが、実際にはGoコンパイラはGCCなどのCコンパイラほど高度ではないため、これはCよりも少し遅く実行されます)
  • オブジェクトのファイナライザをサポート
  • 弱参照はサポートされていません

Go 1.0ガベージコレクター:

  • Go 1.1と同じですが、ほとんど正確ではなく、ガベージコレクターは保守的です。保守的なGCは、[]バイトなどのオブジェクトを無視できます。

GCを別のGCに交換することは、議論の余地があります。たとえば、次のようになります。

  • 非常に大きなヒープを除いて、世代別GCが全体的に高速になるかどうかは不明です
  • 「安全でない」パッケージは、完全に正確なGCおよび圧縮GCの実装を困難にします

また、現在のガベージコレクターはある程度の並列性を備えているため、マルチコアシステムでより高速に実行できます。
uriel

3
@uriel:はい、私は私の回答の最初の項目でこれについて述べました-「(並列実装)」というテキスト。

この答えはまだ最新ですか?
Kim Stebel

c#ガベージコレクターは正確で、c#のように、
ストの

3
良い履歴ログを作成するために、この回答を1.5.xで更新するのはどうでしょうか。
イスマエル

32

Go 1.8-2017年第1四半期については、以下を参照してください

次のGo 1.5 コンカレントガベージコレクターでは、gcが「ペース」を上げることができる必要があります。このペーパー
提示されている提案は、Go 1.5に役立つかもしれませんが、GoのGCを理解するのにも役立ちます。

1.5 以前の状態を見ることができます(Stop The World:STW)

Go 1.5より前のバージョンでは、Goはパラレルストップザワールド(STW)コレクターを使用していました。
STWコレクションには多くの不利な点がありますが、少なくとも予測可能で制御可能なヒープ拡張動作があります。

https://40.media.tumblr.com/49e6556b94d75de1050c62539680fcf9/tumblr_inline_nr6qq8D9FE1sdck2n_540.jpg

GopherCon 2015プレゼンテーション「Go GC:Go 1.5でのレイテンシー問題の解決」の写真)

STWコレクターの唯一の調整ノブは、コレクション間の相対的なヒープ成長である「GOGC」でした。デフォルト設定の100%では、前回のコレクションの時点で、ヒープサイズがライブヒープサイズの2倍になるたびにガベージコレクションがトリガーされました。

https://docs.google.com/drawings/image?id=sLJ_JvGfPfPnojLlEGLCWkw&rev=1&h=113&w=424&ac=1

STWコレクターのGCタイミング。

Go 1.5では、並行コレクターが導入されています
これにはSTWコレクションよりも多くの利点がありますが、ガベージコレクターの実行中にアプリケーションがメモリを割り当てることができるため、ヒープの増加を制御することが難しくなります

https://40.media.tumblr.com/783c6e557b427a5c023520578740eb94/tumblr_inline_nr6qqpmaJx1sdck2n_540.jpg

GopherCon 2015プレゼンテーション「Go GC:Go 1.5でのレイテンシー問題の解決」の写真)

同じヒープ増加の制限を実現するには、ランタイムがガベージコレクションをより早く開始する必要がありますが、どれだけ早く多くの変数に依存するか、その多くは予測できません。

  • コレクターの開始が早すぎると、アプリケーションがガベージコレクションを実行しすぎて、CPUリソースが浪費されます。
  • コレクターの開始が遅すぎると、アプリケーションが望ましい最大ヒープ増加を超えてしまいます。

同時実行性を犠牲にすることなく適切なバランスを実現するには、ガベージコレクターを慎重に調整する必要があります。

GCペーシングは、ヒープの増加とガベージコレクターによって使用されるCPUの2つの側面に沿って最適化することを目的としています。

https://docs.google.com/drawings/image?id=sEZYCf7Mc0E0EGmy4gho3_w&rev=1&h=235&w=457&ac=1

GCペーシングの設計は、4つのコンポーネントで構成されています。

  1. GCサイクルが必要とするスキャン作業の量の見積もり
  2. ヒープ割り当てがヒープ目標に到達するまでに、ミューテーターがスキャン作業の推定量を実行するためのメカニズム
  3. ミューテーターがCPUバジェットを十分に活用していない場合のバックグラウンドスキャンのスケジューラー、および
  4. GCトリガーの比例コントローラー。

デザインは、CPU時間とヒープ時間という2つの異なる時間の見方のバランスをとってます。

  • CPU時間は標準のウォールクロック時間に似ていますが、時間の経過GOMAXPROCS速くなります。
    つまり、GOMAXPROCS8の場合、1秒ごとに8 CPU秒が経過し、GCは1秒ごとに2秒のCPU時間を取得します。
    CPUスケジューラは、CPU時間を管理します。
  • ヒープ時間の経過はバイト単位で測定され、ミューテーターが割り当てるにつれて前進します。

ヒープ時間とウォール時間の関係は割り当て率に依存し、常に変化する可能性があります。
Mutatorはヒープ時間の経過の管理を支援し、ヒープが目標サイズに達するまでに推定スキャン作業が完了することを保証します。
最後に、トリガーコントローラーは、これら2つの時間ビューを結び付けるフィードバックループを作成し、ヒープ時間とCPU時間の両方の目標を最適化します。


20

これはGCの実装です:

https://github.com/golang/go/blob/master/src/runtime/mgc.go

ソースのドキュメントから:

GCはミューテータースレッドと同時に実行され、タイプが正確(別名:正確)であり、複数のGCスレッドを並行して実行できます。これは、書き込みバリアを使用するマークとスイープの同時実行です。それは非世代的でコンパクトではありません。割り当ては、P割り当て領域ごとに分離されたサイズを使用して行われ、一般的なケースでロックを排除しながら断片化を最小限に抑えます。


8

Go 1.8 GCは、「STWスタックの再スキャンを排除する」という提案により、再び進化する可能性があります

Go 1.7の時点で、制限のない、潜在的に重要なStop-the-World(STW)時間の残りのソースの1つはスタックの再スキャンです。

Yuasaスタイルの削除書き込みバリア[Yuasa '90]Dijkstraスタイルの挿入書き込みバリア[Dijkstra '78]を組み合わせたハイブリッド書き込みバリアに切り替えることで、スタックの再スキャンの必要性を排除することを提案します。

予備実験では、これにより、最悪の場合のSTW時間を50µs未満に短縮できることが示されています。このアプローチにより、STWマークの終端を完全に排除することが実際的になる可能性があります。

発表はここにある、あなたは、関連するソースがコミット見ることができるでd70b0feおよびそれ以前。


3

確かではありませんが、現在の(ヒント)GCはすでにパラレルGCであるか、少なくともWIPだと思います。したがって、stop-the-worldプロパティは適用されないか、近い将来適用されません。おそらく、他の誰かがこれをより詳細に明らかにすることができます。


7
それは、世界のストップです。世界が停止した後、GCが並列実行される可能性があります。あなたはおそらく同時GCを意味しました。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.