コンテンツにスキップ

Go/メモリアロケータ

出典: フリー教科書『ウィキブックス(Wikibooks)』
< Go

Goのメモリ管理システムは元々tcmallocに基づいていましたが、現在では大きく進化しています。以下に主要なポイントを解説します。

主要なデータ構造

[編集]
  1. fixalloc: 固定サイズのオフヒープオブジェクトを管理するフリーリストアロケータ
  2. mheap: mallocヒープで、ページ(8192バイト)単位で管理
  3. mspan: mheapで管理される使用中のページ群
  4. mcentral: 同じサイズクラスのmspanを集めたもの
  5. mcache: P(プロセッサ)ごとのmspanキャッシュ
  6. mstats: 割り当て統計情報

小オブジェクトの割り当てプロセス

[編集]
  1. mcacheでの割り当て:
    • サイズを小さいサイズクラスに切り上げ
    • 対応するmspanのフリービットマップをスキャン
    • ロック不要で高速に処理
  2. mcentralからの取得:
    • mspanに空きがない場合、該当サイズクラスのmspanをmcentralから取得
    • スパン全体を取得するためロックコストを償却
  3. mheapからのページ取得:
    • mcentralのリストが空の場合、mheapからページ群を取得
  4. OSからのメモリ取得:
    • mheapが空または十分な連続ページがない場合、OSから新しいページ群(最低1MB)を割り当て

メモリ解放プロセス

[編集]
  1. 割り当て応答としてスイープ中のmspanはmcacheに返却
  2. 割り当て済みオブジェクトがあるmspanはmcentralのフリーリストに配置
  3. 全てのオブジェクトが解放されたmspanはmheapに返却

大オブジェクトの処理

[編集]
  • mcacheとmcentralをバイパスし、直接mheapを使用

ゼロ初期化の最適化

[編集]
  • `mspan.needzero`がfalseの場合、解放済みスロットは既にゼロ初期化済み
  • trueの場合は割り当て時にゼロ初期化
  • 遅延ゼロ初期化の利点:
    1. スタックフレーム割り当てでゼロ初期化を完全に回避可能
    2. 時間的局所性が向上(プログラムがすぐに書き込む可能性が高い)
    3. 再利用されないページはゼロ初期化しない

仮想メモリレイアウト

[編集]
  • ヒープはアリーナ(64ビットで64MB、32ビットで4MB)の集合で構成
  • 各アリーナには対応するheapArenaオブジェクトがあり、メタデータを保持
  • アリーナマップ(mheap_.arenas)はアドレス空間全体をカバー
  • 連続したアリーナを維持するよう努め、大きなスパン(大きなオブジェクト)がアリーナを跨げるようにする

このアロケータ設計は、小オブジェクトの高速割り当て、大オブジェクトの効率的な処理、メモリ使用量の最適化を実現しています。特に、スレッドローカルなmcacheを使用することで、並行処理環境でのロック競合を最小限に抑えています。