Q. RenderTextureをC#スクリプトから毎フレーム生成しています。しかし、プレイし続けているとスマートフォンのメモリやVRAMを使い果たしてアプリがクラッシュしてしまいます。なぜ自動的に解放されないのですか?
A. Unityの RenderTexture は、内部的にGPUのネイティブテクスチャメモリへのポインタを保持している「マネージド外(アンマネージド)リソース」です。C#の変数がスコープを外れても、ネイティブメモリは自動解放されず残留するため、コード上で手動解放を行う義務があります。
メモリリークを防ぐコード実装パターン
// 良くない例:生成したきり放置(リークの主原因)
void CaptureCamera() {
RenderTexture rt = new RenderTexture(512, 512, 16);
myCamera.targetTexture = rt;
myCamera.Render();
// rtはスコープ外になるが、VRAM上にはRenderTextureインスタンスが残り続ける!
}
// 正しい解決コード例:
private RenderTexture dynamicRT;
void CaptureCameraCorrect() {
// すでにテクスチャが存在している場合は再利用または解放
if (dynamicRT != null) {
dynamicRT.Release();
Destroy(dynamicRT);
}
dynamicRT = new RenderTexture(512, 512, 16);
myCamera.targetTexture = dynamicRT;
myCamera.Render();
}
// オブジェクト破棄時に完全にVRAMメモリから削除
void OnDestroy() {
if (dynamicRT != null) {
dynamicRT.Release();
Destroy(dynamicRT);
}
}