【Unity】Unityで採用されているGCの仕組みとUnity2019からのインクリメンタルGCについて

Unityで採用されているGCの仕組みとUnity2019からのインクリメンタルGCについて簡単にまとめました。

GCガベージコレクション)とは?

たとえばいま、メモリ(ヒープ)が下図のように使われているとします。

f:id:halya_11:20190713185221p:plain

ここで、いくつかのオブジェクトがどこからも参照されなくなったとします。

f:id:halya_11:20190713185648p:plain

通常こういったものをメモリから解放し忘れるとメモリリークとなります。
ただしGCが実装されている環境では、参照されていないものが自動的に解放されます。

f:id:halya_11:20190713185730p:plain

この解放処理をGCといいます。

またGCに関連して、コンパクションと呼ばれる処理もあります。
これはGCでメモリを解放した後に穴あきになった部分を整理する処理です。

f:id:halya_11:20190713185801p:plain

これによってメモリ割り当ての効率が良くなるわけですが、この処理自体にも時間がかかります。
そのため、GCの種類によってはコンパクションはやらないものもあります。

GCの種類

さて前節でGCの種類と書いた通り、GCアルゴリズムにはいくつかの種類が存在します。

これらはそれぞれ違った特徴を持ちますが、使う側の観点からすると
GCを行うときに処理を止めるか、並行して動作するかといった違いがあります。

処理を止めてしまうGCはその特徴からStop the World方式とも呼ばれ、
頻繁にGCが行われてしまうとGCスパイクと呼ばれる処理落ちが目立つようになります。

UnityのGC

さてUnityのGCはBoehm GCというものが使われているようです。

これはStop the World方式のGCなので、メモリの使い方に気を付けないとGCスパイクが頻繁に発生します。
またBoehm GCではコンパクションは行わないようです。

インクリメンタルガベージコレクション

Unity2019.1a10でインクリメンタルガベージコレクションがExperimentalな機能として追加されました。

blogs.unity3d.com

これはStop the WorldによるGCスパイクを軽減するための機能です。

正確に言うとGCアルゴリズム自体は変わっていないのでStop the World方式ではあるのですが、
GCの処理を複数フレームにわたって行うことで1フレーム当たりの処理負荷を下げているようです。

GCスパイクが問題になりやすいモバイルビルドでも使えるようなので今後主流になってくるかもしれません。

参考

docs.unity3d.com

developer.aiming-inc.com

ja.wikipedia.org

ufcpp.net

blogs.unity3d.com