2

Windows サービスで system.drawing を集中的に使用しているときに、メモリ不足の例外が発生します。

ここに私のコードの一部があります:

FileStream fs = new FileStream(ImagePath, FileMode.Open, FileAccess.Read);
img = (Image)Image.FromStream(fs).Clone();

例外はこの点で発生するだけでなく、描画、トリミング、サイズ変更、画像のコピーを含む他の点でも発生することがあります

私は常に使用済みのオブジェクトをすべて処分しています。

system.drawing の「メモリ不足例外」に関するこの記事を見まし た ここ

私の場合と非常によく似ていますが、私のテスト データは 40 枚の画像の繰り返しのチェーンであるため、異なるものです。

ここで言及されている制限を見ました

Win/Web サービスでは system.drawing を使用すべきではないと書かれています。

大規模な画像処理のために Windows サービスで使用する必要があります。

4

4 に答える 4

1

Image呼び出しているオブジェクトは破棄さCloneれません(コードに他の同様の間違いがある可能性があります)。このようなオブジェクトによって消費されたメモリは、ファイナライザーの実行後にのみ解放されます。これには、少なくとも2つのGCサイクルが必要でありOutOfMemoryException、最初のGCでスローされる可能性があります。
正しく廃棄すると、次のようになります。

FileStream fs = new FileStream(ImagePath, FileMode.Open, FileAccess.Read);
using(var tmp = Image.FromStream(fs))
  img = (Image)tmp.Clone();
// dispose fs an img after use like usually

または、ファイル全体をに読み込んでにMemoryStream渡すこともできます。Image.FromStreamこれは、画像が2回解析されないことを意味し、追加のリソースを節約する必要があります。

于 2010-01-26T14:06:48.170 に答える
0

なぜ画像のクローンを作成するのですか?あなたの例では、ファイルからデータを読み取り、コピーを作成しています。オブジェクトのスループットが高いサービスでメモリ不足の例外をスローするのにそれほど時間はかかりません。

あなたは単にこれを行うことができます:

var img = Image.FromFile(ImagePath);
于 2010-01-26T13:34:13.580 に答える
0

使用しているメモリが速すぎて、おそらくできるだけ早く解放しないでしょう。

リソースをより保守的にするためにコードをリファクタリングする必要があります。また、必要以上に大きなオブジェクトを保持しないようにし、IDisposableをできるだけ早く破棄するようにしてください。

このプロセスは簡単ではなく、このようなフォーラムで完全に回答することもできません。

于 2010-01-26T13:38:01.370 に答える
0

これは関係ないかもしれませんが...

C ++でビットマップを操作する際に問題が発生し、低レベルのWindowsAPIからリソース不足のエラーが発生しました。これは、描画がbitbltsなどで行われているときに、Windowsの内部リソースヒープがビットマップ/ビットマップセクションを処理/割り当てできないことが原因であると思われます。

チェーンのさらに下にあるこのようなものがドットネットライブラリをトリップしている可能性があるかどうかはわかりません。MSDNのどこかに、デバイスドライバーをインストールし、さまざまなデスクトップヒープを調べるために使用できるツールがあります(それがサービスにどのように関連するかはわかりません)。 / available-それはいくつかの指標になる可能性がありますが、これらの領域の断片化も発生してエラーが発生する可能性があると思います-残念ながら、問題を完全に排除することはできませんでしたが、そのツールは問題の診断に役立つ可能性があります。(ツールは「dheapmon」と呼ばれる可能性があるようです。)

于 2010-02-01T13:50:09.023 に答える