Goはガベージコレクションされた言語です。
http://golang.org/doc/go_faq.html#garbage_collection
ここでは、それはマークアンドスイープガベージコレクターであると述べていますが、詳細については掘り下げておらず、置き換えは作業中です...しかし、この段落はGoがリリースされてからあまり更新されていないようです。
まだマークアンドスイープですか?保守的ですか、それとも正確ですか?世代的ですか?
Go 1.4+ガベージコレクターの計画:
Go 1.1のGo 1.3ガベージコレクターの更新:
Go 1.1ガベージコレクター:
Go 1.0ガベージコレクター:
GCを別のGCに置き換えることは議論の余地があります。例えば:
次のGo 1.5 concurrent Garbage Collectorは、gcが「ペース」できるようにすることを伴います。
ここに提案があります このペーパーで Go 1.5に合うかもしれませんが、Goのgcの理解にも役立ちます。
状態を確認できますbefore 1.5(Stop The World:STW)
Go 1.5より前は、Goはparallel stop-the-world(STW)コレクターを使用していました。
STWコレクションには多くの欠点がありますが、少なくとも予測可能で制御可能なヒープ成長動作があります。
(写真 GopherCon 2015 プレゼンテーション " Go GC:Go 1.5でのレイテンシー問題の解決 ")
STWコレクターの唯一のチューニングノブは、コレクション間の相対的なヒープ成長である「GOGC」でした。デフォルト設定の100%は、以前のコレクションの時点でヒープサイズがライブヒープサイズの2倍になるたびに、ガベージコレクションをトリガーしました。
STWコレクターのGCタイミング。
Go 1.5では、並行コレクターが導入されました。
これには、STWコレクションに比べて多くの利点がありますが、mは、ガベージコレクターの実行中にアプリケーションがメモリを割り当てることができるため、制御が難しくなります。
(写真 GopherCon 2015 プレゼンテーション " Go GC:Go 1.5でのレイテンシー問題の解決 ")
同じヒープの増加制限を達成するには、ランタイムはガベージコレクションを早めに開始する必要がありますが、どれだけ早いかは多くの変数に依存し、その多くは予測できません。
- コレクターの起動が早すぎると、アプリケーションが実行するガベージコレクションが多すぎて、CPUリソースが無駄になります。
- コレクターの開始が遅すぎると、アプリケーションは必要な最大ヒープ成長を超えます。
並行性を犠牲にすることなく適切なバランスを達成するには、ガベージコレクターを慎重にペーシングする必要があります。
GCペーシングは、ヒープの成長とガベージコレクターが使用するCPUの2つの次元に沿って最適化することを目的としています。
GCペーシングの設計は、4つのコンポーネントで構成されています。
- gCサイクルに必要なスキャン作業量の推定値、
- ヒープ割り当てがヒープの目標に達するまでに、ミューテーターが推定量のスキャン作業を実行するメカニズム
- ミューテーターがCPUバジェットを十分に活用していない場合のバックグラウンドスキャンのスケジューラー
- gCトリガーの比例コントローラー。
設計は、CPU時間とヒープ時間の2つの異なる時間のビューのバランスをとります。
- CPU時間は標準のウォールクロック時間に似ていますが、
GOMAXPROCS
倍速くなります。
つまり、GOMAXPROCS
が8の場合、毎秒8 CPU秒が経過し、GCは毎秒2秒のCPU時間を取得します。
CPUスケジューラはCPU時間を管理します。- ヒープ時間の経過はバイト単位で測定され、ミューテーターが割り当てると前進します。
ヒープ時間とウォール時間の関係は、割り当て率に依存し、常に変化します。
ミューテーターは、ヒープの経過時間の管理を支援し、ヒープが目標サイズに達するまでに推定スキャン作業が完了するようにします。
最後に、トリガーコントローラーは、これら2つの時間のビューを結び付けるフィードバックループを作成し、ヒープ時間とCPU時間の両方の目標を最適化します。
これはGCの実装です。
https://github.com/golang/go/blob/master/src/runtime/mgc.go
ソースのドキュメントから:
GCは、ミューテータースレッドと同時に実行され、タイプアキュレート(正確)であり、複数のGCスレッドを並行して実行できます。書き込みバリアを使用するマークとスイープの同時実行です。それは非世代的でコンパクトではありません。割り当ては、P割り当て領域ごとに分離されたサイズを使用して行われ、一般的な場合のロックを排除しながら断片化を最小限に抑えます。
Go 1.8 GCは、 提案「STWスタックの再スキャンの排除」 で再び進化する可能性があります
Go 1.7の時点で、無限で潜在的に自明でないstop-the-world(STW)時間の残りの1つのソースは、スタックの再スキャンです。
Yuasaスタイルの削除書き込みバリア[Yuasa '90] と Dijkstraスタイルの挿入書き込みを組み合わせたハイブリッド書き込みバリアに切り替えることにより、スタックの再スキャンの必要性を排除することを提案します。バリア[ダイクストラ'78] 。
予備実験では、これにより最悪のSTW時間を50µs未満に短縮が可能であり、このアプローチにより、STWマークの終端を完全に排除できることが示されています。
確かではありませんが、現在の(ヒント)GCはすでに並列のものであるか、少なくともWIPであると思います。したがって、stop-the-worldプロパティは適用されないか、近い将来に適用されません。おそらく他の誰かがこれをより詳細に明らかにすることができます。