コガネブログ

平日更新を目標にUnityやC#、Visual Studioなどのゲーム開発アレコレを書いていきます

【Unity】開発中のアプリがメモリリークで強制終了するようになった時に対応したこと

  • インスタンスが破棄される時にメンバ変数に定義しているすべてのデリゲートにnullを代入するようにした

MonoBehaviour を継承しているクラスの場合

  • OnDestroy 関数ですべてのデリゲートにnullを代入する

対応前

public class Example : MonoBehaviour
{
    public Action     mCompleted;
    public Func<bool> mCanPlay  ;
}

対応後

public class Example : MonoBehaviour
{
    public Action     mCompleted;
    public Func<bool> mCanPlay  ;
    
    private void OnDestroy()
    {
        mCompleted = null;
        mCanPlay   = null;
    }
}

MonoBehaviour を継承していないクラスの場合

  • IDisposable インターフェースを実装する
  • Dispose 関数を定義してすべてのデリゲートにnullを代入する
  • Dispose 関数を MonoBehaviour を継承しているクラスの OnDestroy で呼び出す

対応前

public class Hoge
{
    public Action     mCompleted;
    public Func<bool> mCanPlay  ;
}

public class Example : MonoBehaviour
{
    private Hoge m_hoge = new Hoge();
}

対応後

public class Hoge : IDisposable
{
    public Action     mCompleted;
    public Func<bool> mCanPlay  ;
    
    public void Dispose()
    {
        mCompleted = null;
        mCanPlay   = null;
    }
}

public class Example : MonoBehaviour
{
    private Hoge m_hoge = new Hoge();
    
    private void OnDestroy()
    {
        m_hoge.Dispose();
    }
}
  • IDisposable は実装する必要はないが、わかりやすくするために実装した

メモ

  • プロファイラを見ていても、何がリークしているのかがわからなかった
  • Cygames さんのスライドで、デリゲートには null を代入すると良いと知っていたので、開発中もデリゲートに null を代入するようにしていたが、いくつか null を代入していないデリゲートが存在した
  • ソースコードを見直して、null を代入していないデリゲートにも null を代入するようにしたところ、強制終了の不具合が直った

参考資料

speakerdeck.com