本日はUnityの小ネタ枠です。
Unityでガベージコレクションの有効無効を切り替える方法です。
ガベージコレクションとは
ガベージコレクションは使用されなくなったメモリ領域を自動的に解放するメモリ管理機能です。
C#では.NET Frameworkが提供するGCが動作しており、開発者が明示的にメモリを解放する必要がありません。
一方でGCが実行されるタイミングで一時的に処理が停止するため、フレームドロップの原因となる可能性があります。
UnityでのGC制御
GarbageCollector
Unity 2018.3以降では GarbageCollector クラスが導入され、Unity独自のGC制御が可能になりました。
GarbageCollectorクラスを使うことで、MonoやIL2CPP環境でGCの有効・無効を切り替えることができます。
docs.unity3d.com
GCを一時的に停止することで、リアルタイム性が求められる処理中にGCによるフレーム落ちを防ぐことができます。
ただし、GCを無効化している間は不要なメモリが解放されないため、メモリ使用量が増加する点に注意が必要です。
// GCを無効化 GarbageCollector.GCMode = GarbageCollector.Mode.Disabled; // GCを有効化 GarbageCollector.GCMode = GarbageCollector.Mode.Enabled;
Incremental GC
Unity 2019.1.0以降では、更にIncremental GC(インクリメンタルガベージコレクション)の仕組みが導入されました。
Incremental GCは従来のガベージコレクション処理を複数フレームに分割して少しずつ実行することで、1フレームあたりのGC負荷を軽減します。
これにより、GCによる一時的なフレームレート低下(ラグ)が発生しにくくなり、リアルタイム性が求められるゲームやアプリケーションでより安定したパフォーマンスが得られます。
Incremental GCは以下の手順で設定可能です。
メニューから[Edit -> Project Settings]を開き、[Player]タブを開きます。

[Other Settings -> Configuration -> Use Incremental GC]にチェックを入れることで有効になります。

また、Incremental GCは GarbageCollector クラスを通じて制御できます。
// Incremental GCが有効かどうか bool isIncremental = GarbageCollector.isIncremental; // Incremental GCの目標時間(ナノ秒) ulong incrementalTime = GarbageCollector.incrementalTimeSliceNanoseconds; // Incremental GCを指定時間(ナノ秒)だけ実行する // 返り値は実行すべきガベージコレクション作業があるかどうか bool isCollectIn = GarbageCollector.CollectIncremental(1000);
docs.unity3d.com
docs.unity3d.com
なお、WebGLプラットフォームはIncremental GCをサポートしていません。
環境によっては利用できない点に注意が必要です。
docs.unity3d.com