こんにちは、Unityエンジニアのオオバです。

RenderTextureを動的にスクリプトから生成して、Blitしてごにょにょするというフローの中で、どのタイミングでメモリが確保され、いつ解放されるのか確認したいと思います。

メモリのプロファイルということでUnity製MemoryProfilerを使います。
本環境はUnity2018.3.0f2なので、PackageManagerから0.1.0-preview.3をダウンロードします。

Unity RenderTextureのメモリ確保と解放タイミングの落とし穴_0

👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

メモリ確保タイミングの確認

メモリが確保される予測タイミングは、

この2パターンかなと思っています。

とりあえずEditor上でプロファイリングしていきます。

RenderTextureをnewして生成する

実行前実行後

Unity RenderTextureのメモリ確保と解放タイミングの落とし穴_1

93.4MB | 1.59GB

※実行前に存在するRenderTexutureはUnityエディタのシーンView、GameView表示のためにデフォルトで用意されているものです

わかりやすくするためにW2048×H2048pxのRenderTextureを50枚生成した結果がコチラです。
この結果から

「RenderTextureをnewして生成した時」

がメモリ確保タイミングということだとわかります。

ただし、これはあくまでUnityエディタ上でのプロファイリングなので実機上で確認してみます。

実機からUnityのMemoryProfilerに接続して同様に確認してみます。

実行前実行後

Unity RenderTextureのメモリ確保と解放タイミングの落とし穴_2

0MB | 1.56GB

予想通り、newしたタイミングでRenderTextureのメモリが確保されました。

ここまで引っ張っておいてあれですが、これは間違いです。

XcodeとUnityにおける値の乖離

Unity RenderTextureのメモリ確保と解放タイミングの落とし穴_3

Xcodeのメモリ使用率を見てみると、90MBと値が1.5GBと比べて大きく乖離していることがわかりました。

Unity上Xcode上
1.5GB90MB

これはUnityのMemoryProfilerが認識している確保と実際の確保タイミングが違うのではないかということが推測されます。
ということで、第2の予測RenderTextureにピクセルを書き込んだタイミングを確認してみます。

RenderTextureに書き込んだ瞬間、iPhone6sはフリーズし、真っ暗なが画面になり、再起動をし始めました。
Xcode上に以下のダイイングメッセージのような結果を残して。

Unity RenderTextureのメモリ確保と解放タイミングの落とし穴_4

iPhone6sのメモリは最大2GBなので、1.5GBも使ってしまうとそりゃ死にます(もっと早くに気づけたはずorz)。

ということで、メモリの確保のタイミングというのは、

「ピクセルを書き込んだ時」

ということが分かりました。
続いてメモリ解放タイミングについて調べていきます。

メモリ解放タイミングの確認

メモリが解放される予測タイミングは2通りです。

確保時同様まずはUnityエディタ上で、MemoryProfilerで確認していきます。

結論から言うと、Unityエディタ上ではReleaseタイミングでは何も起きず、Destroyした直後にメモリから開放されました。

Unityエディタ上での挙動はあてにならないので、確保時同様、実機で確認してみます。

Unity RenderTextureのメモリ確保と解放タイミングの落とし穴_5

結論から言うと、「RenderTextureをDestroyした時」「RenderTextureをReleaseした時」どちらも同様にメモリが開放されます。GCが走ることなく、Destroyを呼んだ直後に開放されます。

RenderTextureのメモリを解放するのはReleaseが良いの?Destroyが良いの?

まとめ

RenderTextureの確保はピクセルを書き込んだ時、開放するタイミングはRelease時 or Destroy時ということです。
改めて実機上での挙動を確認する重要性に気付かされました。少々面倒くさくても実機でプロファイリングする癖を付けるのは開発する上では超重要だということですな。

今回のサンプルコートはコチラ
RenderTextureMemoryAlloc.cs · GitHub

Unity RenderTextureのメモリ確保と解放タイミングの落とし穴_6

画面上のボタンをポチポチ押しながら確認します。

以上

参考

オススメ記事
検証環境