1

ループで実行される次のコードがあります。

public void Test(Bitmap bmp)
{
   FormatConvertedBitmap fBitmapSource = new FormatConvertedBitmap();
   PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
   BitmapImage bi = new BitmapImage();

   using (MemoryStream ms = new MemoryStream())
   {
      bmp.Save(ms, ImageFormat.Png);
      bmp.Dispose();
      bmp = null;

      bi.BeginInit();
      bi.StreamSource = ms;
      bi.EndInit();

      BitmapPalette pallete = new BitmapPalette(bi, 256);
      ...

最終行

BitmapPalette pallete = new BitmapPalette(bi, 256);

次の例外がスローされることがあります

Insufficient memory to continue the execution of the program.at System.Windows.Media.Imaging.BitmapPalette..ctor(BitmapSource bitmapSource, Int32 maxColorCount)

何か案は ?実行を継続するのに十分なメモリがあることは明らかです。

4

1 に答える 1

2

管理対象プログラムには、管理対象メモリの不足とは関係のないOutOfMemoryExceptionの他のソースがあります。例外は、レガシーネイティブコードによって返されたエラーコードを変換するときにも発生します。COMメソッド呼び出しによって返される可能性のあるE_OUTOFMEMORYエラーのように。そして、あなたの場合、GDI+によって関連しています。失敗を示す20の異なるエラーコードしかないので、この回答に文書化されています。それらの1つはOutOfMemoryです。

これは複数のことを意味する可能性があります。管理されていないメモリが不足しているため、GDI+がビットマップピクセルを格納するために使用する種類は確かに可能性があります。また、プロセスで使用可能なGDIオブジェクトハンドルが不足していることを意味する場合もあります。Windowsでは、10,000GDIハンドルのハンドルクォータが課されます。これは膨大な数ですが、その割り当てを超えると、ほとんどの場合、コードにバグがあることを示します。ハンドルリーク。これは、管理対象プログラムの場合、ほとんどの場合、Image.Dispose()メソッドの使用を忘れ、ファイナライザーがハンドルを解放できるほど頻繁にガベージコレクターを実行しないことが原因です。

残念ながら、破損したビットマップデータによってトリガーされることもありますが、パレットの割り当てを爆撃するため、この場合は発生しない可能性があります。これは、Taskmgr.exeの[プロセス]タブですぐに確認できるはずのハンドルリークを示しています。列を表示+選択し、GDIオブジェクトにチェックマークを付けます。テスト中は、プロセスの表示値に注意してください。着実に増加している数は問題を引き起こします、それが10,000に達するとき、ショーは終わります。また、「コミットサイズ」列も確認してください。これは、管理されていないメモリを大量に消費する問題を示している可能性があります。

于 2012-05-30T13:32:13.190 に答える