コガネブログ

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

【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

関連記事