한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

ゲームラグ白書 › L1 クライアントのゲームプロセス

クライアントのガベージコレクション Client GC (Unity C#, Unreal, Lua)

原因ID cg-gc · 主担当 ゲーム開発チーム・クライアント開発

図と実験のあるメインページでこのカードを開く →

使い終わったメモリ(ガベージ)を回収する間、ゲーム全体が止まります。一定の間隔でカクつくのが特徴です。

なぜ 毎フレーム、一時的な文字列・配列・リストを作っては捨てる → すると ガベージがたまると、GCがメインスレッドを止めて回収 → 画面では 数秒〜数十秒ごとに規則的にカクつく

症状
カクつき, フリーズ
要因
ストール
誰に起きるか
自分だけ
いつ
一定の周期で, 人が集中したとき
担当
主担当 ゲーム開発チーム・クライアント開発
ゲーム開発チームの対応
アロケーションの削減(文字列連結・LINQ・ラムダのキャプチャを避ける)、オブジェクトプール、インクリメンタルGCを有効のままにする(Unity 2020以降のデフォルト)、ロード画面のように止まっても問題ないタイミングで先にGCを実行。
数値の目安
通常は1回あたり数ms〜100ms、低スペックのスマホやメモリを多く使うゲームではそれ以上(実験では約150〜170ms)。UnityのGCは実行のたびにヒープ全体を調べるため、ゲームが使っているメモリが多いほど長くなります。
グラフでは
周期的なスパイク · フレームタイム、GCの実行時刻
確認箇所
開発ビルドで、UnityプロファイラーのGC.Collect・GC.Allocマーカーを確認。Unrealはstat GCとstat Hitches(t.HitchFrameTimeThresholdで指定した時間を超えるフレームをログに記録)
該当する場合
跳ねたフレームごとにGC.Collectの区間があり、その長さが跳ねた長さとほぼ同じで、間隔が数秒〜数十秒と規則的。人が多い場所ではフレームあたりのGC.Allocが増える
該当しない場合
跳ねたフレームにGCの区間がなければ「メインスレッドでの同期ロード・シェーダーコンパイル」か「大人数の描画負荷」
確認手段
ゲームサーバー・クライアントのログ・メトリクスが必要
もっと詳しく
UnityのようにC#を使うクライアントでよく起きます。戦闘ログの文字列、ダメージの数字、UIテキストを毎フレーム新しく作るコードが主な原因です。人が多い場所でだけカクつくなら、人数に比例してガベージが増えるコードがあるということです。インクリメンタルGCは1フレームに少しずつ(Unityのデフォルトは3ms)分けて回収しますが、回収する速度よりも速くガベージを生み出すと、結局一度にまとめて止まります。Unreal Engineにも使われなくなったゲームオブジェクトを片付ける独自のGCがあり、エンジンのバージョンや設定によって異なりますが、デフォルト設定では約1分ごとに実行され、1分間隔で一瞬止まる原因になることもあります。ゲームのルールをLuaのようなスクリプトで書いたクライアントでは、そのスクリプトのGCも別に動きます。

出典

  1. Garbage collection modes Unity
    インクリメンタルGCがデフォルトで、複数フレームに分けて回収する。無効にするとヒープ全体を調べる間メインスレッドが止まり、数百msに達することもある
  2. Scripting.GarbageCollector.CollectIncremental Unity
    インクリメンタルGCが1回に使う時間(タイムスライス)のデフォルトの目標は3ms(incrementalTimeSliceNanoseconds)
  3. Garbage Collection Settings in the Unreal Engine Project Settings Epic Games
    UnrealのGCが決まった間隔(Time Between Purging Pending Kill Objects、秒単位)で実行されることを示す設定。デフォルト値の数字はこの文書には記載なし
  4. Profiler markers reference Unity
    GC.Collect:ガベージコレクション中にプログラムのコードが止まった区間(1ms未満〜数百ms)、GC.Alloc:マネージヒープへのアロケーション
  5. Stat Commands in Unreal Engine Epic Games
    stat GC(ガベージコレクションの統計)、stat Hitches(t.HitchFrameTimeThresholdを超えるフレームをログに記録)

あわせて読みたい原因

同じ層:L1 クライアントのゲームプロセス

同じ症状(カクつき)を起こすほかの層の原因

図と実験のあるメインページでこのカードを見る