2012-05-30 2 views
1

У меня есть следующий фрагмент кода, который работает в цикле.BitmapPalette Недостаточно памяти исключение

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) 

Любые идеи? У меня явно хватает памяти для продолжения исполнения.

+0

Уверены ли вы, что у вас «явно» достаточно? – MoonKnight

+0

Вы говорите, что этот код работает в цикле - возникает ли ошибка при первом проходе через цикл или позже? Если позже, сколько проходит через шаблон цикла перед исключением? – Oliver

+0

Killercam: У меня явно хватает памяти. – user510799

ответ

2

В управляемой программе есть другие источники OutOfMemoryException, которые не имеют никакого отношения к исчерпанию управляемой памяти. Исключение также возникает, когда оно преобразует коды ошибок, возвращаемые устаревшим кодом. Подобно ошибке E_OUTOFMEMORY, которая может быть возвращена вызовами метода COM. И уместно в вашем случае, GDI +. Который содержит только 20 различных кодов ошибок, указывающих на сбой, вы найдете их задокументированными в this answer. Один из них - OutOfMemory.

Это может означать не одно. Запуск неуправляемой памяти, вид, используемый GDI + для хранения растровых пикселей, безусловно, возможен. Это также может означать, что в вашем процессе закончились доступные дескрипторы объектов GDI, Windows накладывает квоту дескриптора в 10 000 дескрипторов GDI. Что представляет собой огромное количество битв, превышающее эту квоту, почти всегда указывает на ошибку в коде. Утечка ручки. Который в случае управляемой программы почти всегда вызван тем, что забыл использовать метод Image.Dispose() и не иметь сборщик мусора, который работает достаточно часто, чтобы позволить финализатору выпускать дескрипторы.

К сожалению, это может быть даже вызвано поврежденными растровыми данными, что вряд ли возможно в вашем случае, так как вы бомбите выделение палитры. Это указывает на утечку рукоятки, которая должна быть легко видна на вкладке «Процессы» Taskmgr.exe. Открыть + Выбрать столбцы и отметить объекты GDI. Следите за отображаемым значением для вашего процесса, пока вы его проверяете. Постоянно увеличивающееся количество заклинаний вызывает проблемы, шоу заканчивается, когда оно достигает 10 000. Также посмотрите на столбец «Размер фиксации», который может показать вам проблемы с потреблением слишком много неуправляемой памяти.

Смежные вопросы