げんさん日記

プログラミングで気付いた事等を書きます。

メモリリーク対策

2019年09月12日 14時43分01秒 | C#
C#のプログラミングで気を付けないといけないのがメモリリークです。通常のシステム開発ではそれ程気にしなくても良いのですが画像処理等メモリを多く使う場合やWPFにおいてメモリリークは問題になってきます。
その対策方法としてモデルのベースに解放処理を組み込み、PGではUsingを使用し確実なメモリの解放を行うこととする。
下記にその内容を記述します。

Dispose中かを判断するフラグを用意する。
public abstract class BaseModel : IDisposable
{
  protected bool IsDisposed { get; set; } = false;
}

継承するDisposeメソッドを定義します。
protected virtual void Dispose(bool disposing)
{
  // 終了処理中でない時、下記処理を行う。
  if (this.IsDisposed == false)
  {
    if (disposing == true)
    {
      // ガーベージコレクションを解放します。
      // ※自分のみを解放します。(全てを解放すると処理がすごく重くなります。)
      GC.SuppressFinalize(this);
    }
  this.Disposed = true;
}

パブリックのDisposeメソッドを定義します。
public void Dispose()
{
  // Dispose(引数:true)を呼び出します。
  this.Dispose(true);
}

ファイナライザを定義します。
~BaseModel()
{
  // Dispose(引数:false)を呼び出します。
  this.Dispose(false);
}

継承モデル例
public class Test : BaseModel
{
  protected override void Dispose(bool disposing)
  {
    // 終了処理でない時に処理を行う。
    if (this.IsDisposed == false)
    {
      // 管理外のオブジェクトを解放する。
      ・・・
      // ベースのDisposeを呼び出す。
      base.Dispose(disposing);
    }
  }
}

使用例
public class Main
{
  public Main()
  {
    // Usingで処理することで確実にメモリの解放を行える。
    using (var model = new Test()
    {
      ・・・
    }
  }
}