WCF サービスで BufferManager を使用しています。IDisposable を実装する BufferManager をラップする独自のクラスを作成しました。現在、私の Dispose メソッドは次のようになっています。
public void Dispose()
{
this.bufferManager.Clear();
}
私の質問:これは、マネージャーによって取得されたすべてのバッファーで ReturnBuffer を呼び出すのと同じことを達成しますか?
背景として: 次のメソッドで BufferManager を使用しています。
public byte[] ReadAllBufferedBytes(string filePath)
{
using (var fileStream =
new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = this.bufferManager.TakeBuffer((int)fileStream.Length);
fileStream.Read(buffer, 0, buffer.Length);
return buffer;
}
}
私がこれを行っている理由は、サービスを破壊する OutOfMemory 例外を取得し続けたためです。
ホスト サーバーには 3 GB のメモリがあります。サービスは InstanceContextMode.Single モードであるため、画像は一度に 1 つずつ処理されます。画像はバイト配列として受信されます - 最大のものは 100MB かもしれませんが、通常ははるかに小さくなります - 変換され、バイト配列として返されます。多くのものがラージ オブジェクト ヒープに置かれ、画像のサイズはかなり異なります。
問題がヒープの断片化であるかどうか疑問に思っています。
ドキュメントの各ページが変換されると、ディスク上の一時ファイルに追加されます。変換後、変換されたファイル全体をディスクからバイト配列に読み取り、それをクライアントに返します。
標準の File.ReadAllBytes メソッドは、ファイルから読み取るときに新しいバイト配列を作成します。これは、作業している画像サイズのために必然的に LOH になります (これが起こると思います)。ReadAllBufferedBytes メソッドを作成して同じことを行いましたが、バイト配列をバッファリングし、BufferManager が破棄されたときにバッファを返せるようにしました。
もう 1 つの質問は、これをすべて行う必要があるかどうかです。