今回はUnityのIncremental GCの設定について見ていきたいと思います。
GCはGarbage Collectionの略で不要になったメモリ領域を解放する機能です。
このガベージコレクションがメモリの割り当てや解放を行う処理が多く実行されると、その間ゲームが一時的に止まってしまうということが起こりえます。
ガベージコレクションの処理で動作が一時的に止まってしまうのを避ける為、メモリの割り当てをする回数を少なくする等の最適化の処理を実行する必要があります。
しかし、どうしても1フレーム内のGCの処理が大きくてどうしようもない時は、設定でIncremental GCを有効にして複数フレームに渡ってGCを実行するように変更出来ます。
複数フレームに処理を分けるのでGCが1フレームに実行する処理が少なくなり、GCの山のスパイクがなだらかになります。
複数フレームで実行するので全体的に処理が遅くなります。
Incremental GCを有効にすると必ずしも問題が解決するわけではないので注意が必要です。
Incremental GCを有効にする
Incremental GCを有効にするにはUnityメニューのEditからProject Settings→Playerを選択し、ConfigulationのUse Incremental GCにチェックを入れます。
元々チェックが入っている場合もあります。
ただし、WebGL等のプラットフォームではIncremental GCは機能しません(設定を変更出来ない)。
現在有効なのは以下のプラットフォームです。
Mac Standalone player
Windows Standalone player
Linux Standalone player
iOS
Android
Windows UWP player
PS4
Xbox One
Nintendo Switch
Unity Editor
有効にした時の効果
サンプルを作成して効果を確認してみます(同じようにサンプルを作る必要はありません)。
以下のようなスクリプトを作成し、毎フレーム参照変数の作成とテキストへの出力をしてゴミを発生させます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class IncrementalGarbageCollectionTest : MonoBehaviour { [SerializeField] private Text outputText; // Update is called once per frame void Update() { // int型配列を500作成 for (int i = 0; i < 500; i++) { // 500の要素を持つint型の配列を確保 int[] array = new int[500]; // 各配列の要素に値を入れテキストに出力 for (int j = 0; j < 500; j++) { array[j] = j; outputText.text = array[j].ToString(); } } } } |
スクリプトをMain Camera等に取り付けて実行します。
Incremental GCが無効の状態の時にUnityのプロファイラーを見ると以下のようになります。
Incremental GCを有効にすると以下のようになります。
無効の時は1フレームでGCの処理を実行しているのでグラフが急ですが、有効にすると他のフレームの処理も遅くなりますがなだらかになっています。