ゲームラグ白書 › L10 メモリ
メモリの断片化 Heap fragmentation
原因ID mem-fragment · 主担当 ゲーム開発チーム・サーバー開発
図と実験のあるメインページでこのカードを開く →
アロケーションと解放を繰り返して空き領域が細かく分断されると、実際に使っている量よりはるかに多くのメモリを占有するようになります。
なぜ サイズがまちまちのメモリを、複数のスレッドが長期間アロケーション・解放 → すると 空き領域が細かく散らばってOSに返せず、使用量がリークのように増え続ける → 画面では 長く稼働するほどスワップ・メモリ不足で遅くなり、最後は強制終了
- 症状
- スローモーション, 切断
- 要因
- ストール
- 誰に起きるか
- サーバー全体
- いつ
- 長時間稼働するほど
- 担当
- 主担当 ゲーム開発チーム・サーバー開発
- ゲーム開発チームの対応
- サイズ別のメモリプール、断片化に強いアロケーター(jemalloc、mimallocなど)。
- グラフでは
- 徐々に上昇 · プロセスのメモリ(RSS)
- 確認箇所
- 同じビルドのサーバーを2つ起動し、片方だけ環境変数MALLOC_ARENA_MAXでglibcのアリーナ数を減らすか、jemallocなど別のアロケーターに替えて、数日間pidstat -rのRSSを比較
- 該当する場合
- 人数・オブジェクト数はほぼ同じなのに、変更したサーバーだけRSSの増加が止まるか大きく減る
- 該当しない場合
- アロケーターを替えても同じように上がるなら、解放されないメモリ(mem-leak)
- 確認手段
- インフラのツールで確認(ゲームコード不要)
- もっと詳しく
- リークと同じ形になるため、ヒープを解析してもリーク箇所は見つかりません。Linuxの標準アロケーター(glibc)はスレッドの多いサーバーで特にひどく、アロケーターを替えるだけで使用量が大きく減ることもあります。
出典
- mallopt(3) — Linux manual page Linux man-pages
glibc mallocはスレッド競合を減らすためにアリーナをCPU数の倍数まで作成し、アリーナが多いほどメモリ使用量が増える(M_ARENA_MAXで制限、環境変数MALLOC_ARENA_MAXでも設定可能) - jemalloc memory allocator jemalloc
断片化の回避と並行処理でのスケーラビリティを重視した汎用のmalloc実装 - pidstat(1) — Linux manual page sysstat
-r:プロセスごとのRSS(実際にRAM上にあるメモリ)
あわせて読みたい原因
同じ層:L10 メモリ
同じ症状(スローモーション)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る