Erlang / OTPでのガベージコレクション(GC)とメモリ管理に関する技術的な詳細を知りたいです。
しかし、erlang.orgとそのドキュメントで見つけることができません。
ガベージコレクションアルゴリズムが使用されているなど、非常に一般的な方法でGCについて説明している記事をオンラインで見つけました。
Erlang / OTPでのガベージコレクション(GC)とメモリ管理に関する技術的な詳細を知りたいです。
しかし、erlang.orgとそのドキュメントで見つけることができません。
ガベージコレクションアルゴリズムが使用されているなど、非常に一般的な方法でGCについて説明している記事をオンラインで見つけました。
物事を分類するために、メモリレイアウトを定義してから、GCがどのように機能するかについて説明しましょう。
Erlangでは、実行の各スレッドはプロセスと呼ばれます。各プロセスには独自のメモリがあり、そのメモリレイアウトは、プロセス制御ブロック、スタック、ヒープの3つの部分で構成されています。
PCB:プロセス制御ブロックは、プロセス識別子(PID)、現在のステータス(実行中、待機中)、その登録名などの情報を保持します。
スタック:これは、式を評価するための着信および発信パラメータ、リターンアドレス、ローカル変数、および一時スペースを保持する、下向きに成長するメモリ領域です。
ヒープ:プロセスメールボックスメッセージと複合用語を保持する、上向きに成長するメモリ領域です。64バイトを超えるバイナリ用語は、プロセスのプライベートヒープに格納されません。これらは、すべてのプロセスからアクセスできる大きな共有ヒープに格納されます。
現在、Erlangは、各Erlangプロセスのプライベートヒープ内で個別に実行される世代別ガベージコレクションを使用しています。また、グローバル共有ヒープに対して参照カウントガベージコレクションが発生します。
プライベートヒープGC:世代別であるため、ヒープを若い世代と古い世代の2つのセグメントに分割します。また、収集には2つの戦略があります。ジェネレーション(マイナー)およびフルスイープ(メジャー)。世代別GCは若いヒープを収集するだけですが、フルスイープは若いヒープと古いヒープの両方を収集します。
共有ヒープGC:参照カウントです。共有ヒープ(Refc)内の各オブジェクトには、Erlangプロセスのプライベートヒープ内に格納されている他のオブジェクト(ProcBin)によって保持されているオブジェクトへの参照のカウンターがあります。オブジェクトの参照カウンターがゼロに達すると、オブジェクトにアクセスできなくなり、破棄されます。
詳細とパフォーマンスのヒントを入手するには、答えのソースである私の記事を見てください:Erlangガベージコレクションの詳細とそれが重要な理由
アルゴリズムのリファレンスペーパー: 1995年のJoeArmstrongとRobertVirdingによるOnePass Real-Time Generational Mark-Sweep Garbage Collection(1995) (CiteSeerX)
概要:
従来のマークスイープガベージコレクションアルゴリズムでは、アルゴリズムのマークフェーズが終了するまでデータを再利用できません。破壊的な操作が許可されていない言語のクラスでは、ヒープ内のすべてのポインターが常に「古い」データを逆方向に指すように調整できます。このホワイトペーパーでは、このような言語クラスのデータをシングルパスマークスイープコレクターで再利用するための簡単なスキームを紹介します。また、収集を段階的に実行できるように(リアルタイム収集に適したものにするために)単純なスキームを変更する方法も示します。これに続いて、世代別ガベージコレクション用にコレクターを変更する方法、そして最後に、並行プロセスを持つ言語でスキームを使用する方法を示します。1
Erlangには、GCを実際に非常に簡単にするいくつかのプロパティがあります。
1-すべての変数は不変であるため、変数がその後に作成された値を指すことはありません。
2-値はErlangプロセス間でコピーされるため、プロセスで参照されるメモリはほとんどの場合完全に分離されています。
これらの両方(特に後者)は、収集中にGCがスキャンする必要のあるヒープの量を大幅に制限します。
ErlangはコピーGCを使用しています。GC中、プロセスは停止され、ライブポインタがfrom-spaceからto-spaceにコピーされます。正確なパーセンテージを忘れましたが、収集中にヒープの25%程度しか収集できない場合はヒープが増加し、プロセスヒープの75%が収集できる場合はヒープが減少します。プロセスのヒープがいっぱいになると、コレクションがトリガーされます。
唯一の例外は、別のプロセスに送信される大きな値の場合です。これらは共有スペースにコピーされ、参照カウントされます。共有オブジェクトへの参照が収集されると、カウントが減少し、そのカウントが0の場合、オブジェクトは解放されます。共有ヒープ内の断片化を処理する試みは行われません。
これの興味深い結果の1つは、共有オブジェクトの場合、共有オブジェクトのサイズはプロセスのヒープの計算されたサイズに寄与せず、参照のサイズのみが寄与します。つまり、大きな共有オブジェクトが多数ある場合、GCがトリガーされる前にVMのメモリが不足する可能性があります。
ほとんどの場合、これはJesperWilhelmssonがEUC2012で行った講演から引用したものです。
あなたの経歴はわかりませんが、jj1bdxがすでに指摘している論文とは別に、JesperWilhelmssonの論文にチャンスを与えることもできます。
ところで、Erlangのメモリ使用量を監視してC ++などと比較したい場合は、以下を確認できます。
お役に立てれば!