はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】Unity6.8でCoreCLR GCが導入されてもIL2CPPではBoehm GCなのでGC.Collectの呼び出し方は注意した方が良い話

はじめに

以前XにてBoehm GCを利用する際はGC.Collectを複数回呼ばないとOSに返却されない話をしました。

それに関連して、Unity6.8(実験的にUnity 6.7 Alpha 2)からデスクトップはCoreCLR GCに置き換わります。置き換わると複数回GC.Collect呼ぶ必要もありません。

そのあたりの話を書いていきたいと思います。

IL2CPPのときの注意点

注意点としてIL2CPPでは引き続きBoehm GCを利用するので今まで通り複数回呼ぶ必要があります。

まとめると、

  • デスクトップ: Unity6.8(実験的にUnity 6.7 Alpha 2)からCoreCLR GCに
  • iOS: JITが許可されていないのでIL2CPPが必須でBoehm GCのまま
  • Android: JITは使えるが未対応でBoehm GCのまま

といった感じで、Unity6.8になってもiOS/AndroidはCoreCLR GCではないのに注意です。

GC.Collectの対応の仕方

もしGC.Collectを用いてメモリをOSに返却したいなら、以下のようなコードを書く必要があります。

#if ENABLE_IL2CPP
// Boehm GC
for (var i = 0; i < 7; i++)
{
    GC.Collect();
}
#else
// CoreCLR GC
GC.Collect();
#endif

ENABLE_IL2CPPはIL2CPP ビルド時に有効になる #define ディレクティブです。
docs.unity3d.com

追記. Android + JITのときも判定できないとダメかも。GCの種類でシンボル定義がないとキツい気がするが、おそらく公式にない?

さいごに

ただ本当に手動で実行すべきかどうかは議論があるので、そこは吟味して実行タイミングなどは考えると良いと思います。