4

ネイティブ dll のラッパーであるサードパーティ ライブラリを使用しています。ライブラリには type が含まれ、XImageいくつXImageかのプロパティとIntPtr Data()メソッドがあります。XImageも実装IDisposableしていますが、正しく実装されているかどうかはわかりません。

XImageTCP 接続から多くの を取得し、 PictureBox.

以前は 'XImage' を に変換しSystem.Drawing.Imageて表示していましたPictureBoxが、AccessViolationException.

そこで、 というラッパーを作成しましXImageFrame

public class Frame : IDisposable
{
  public uint size { get; private set; }
  private Image image;
  public XImage XImage { get; set; }
  public Image Image { get { return image ?? (image = GetBitmap(this.XImage)); } }
  public DateTime Time { get; set; }

   public Frame(XImage xImage)
  {
    this.XImage = xImage;
    this.size = XImage.ImageBufferSize();
    GC.AddMemoryPressure(size);
  }


  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }

  ~Frame()
  {
    Dispose(false);
  }

  protected virtual void Dispose(bool disposing)
  {
    if (disposing)
    {
      try
      {
        image.Dispose();
      }
      catch { }
      finally
      {
        image = null;
      }
      try
      {
        MImage.Dispose();
      }
      catch { }
      finally { XImage = null; }
    }
    GC.RemoveMemoryPressure(size);
  }
}

への参照を処理するFrameことで、AccessViolationException. Visual Studio (F5 - デバッグの開始) からプログラムを実行すると、すべて問題ありませんが、.exeファイルまたは (ctrl + F5 - デバッグなしで開始) からプログラムを実行すると、メモリ使用量がどんどん大きくなります。 (ビルド構成: リリース - X86)を取得するまでOutOfMemoryException。私は何をすべきか ?

- - 編集 - -

GC.AddMemoryPressure私は、ガベージコレクションをより頻繁に実行することを発見しましたGC.RemoveMemoryPressure。私の問題は、大きなアンマネージメモリへのハンドルを持つ小さなオブジェクトがあり、GC がこれらの小さなオブジェクトを収集していないことです。

----編集----
呼び出しGC.Collectは実行時に問題を解決します。タイマーを設定してGC.Collect定期的に呼び出しますが、アプリケーションが短時間フリーズするため、このアプローチは使用したくありません。

4

1 に答える 1

0

GCこれには制限があり、非常に大きな負荷がかかる場合やメモリを大量に消費するアプリケーションではうまく機能しない可能性があることがわかりました。アンマネージ リソース (すべての標準 .NET コンポーネント) を直接処理しないアプリケーションがありますが、それでもメモリが不足する可能性があります。GB の RAM を使用できますが、膨大なメモリ要件のためではなく、大きなオブジェクトが比較的迅速に作成および破棄され、明らかにあまり頻繁に収集されないためです。コレクションが強制されるとアプリケーションはすべて解放されるため、アプリケーションにメモリ リークはありません。GC未使用のオブジェクトを時間通りに収集できるとは限らないようですOutOfMemoryException。それは最高の瞬間を見つけるのを待ちますが、決心する前には手遅れです。定期的に収集を強制すると、アプリケーションは問題なく実行されます。

OutOfMemoryException実際に空きメモリが不足しているとは限らないことに注意してください。また、使用可能な十分な大きさの連続したメモリ チャンクがないことを意味する場合もあります。これは、特にビデオや画像を扱う場合に当てはまります。GCまだ十分な空きメモリがあると思うかもしれませんが、アプリケーションには断片化されすぎています。GC断片化を考慮に入れていると確信していますが、常に正しくなるとは限りません。

ライブラリに問題がないと確信している場合は、時間通りに実行できるように、メモリ プレッシャ メソッド ( AddMemoryPressureおよびRemoveMemoryPressure ) をさらに試してみることをお勧めしGCます。の背後で大量のメモリを処理している可能性のある管理されていないライブラリを使用しているため、問題が解決する場合がありますGC。または、 と同じようにしますGC.Collect。手作業による収集は理想的ではないかもしれませんが、それが正当化される場合もあると思います。もちろん、多数のオブジェクトを手動で収集すると、アプリケーションのパフォーマンスに影響を与える可能性があることを想定してください。

編集

手動収集がパフォーマンスに大きな影響を与える場合は、オーバーロードされたバージョンを使用GC.Collectして、もう少し制御できるようにしてください。

于 2012-05-14T10:16:45.290 に答える