Недостаточно памяти в System.Drawing в службе Windows - PullRequest
2 голосов
/ 26 января 2010

Я получаю исключение из памяти при интенсивном использовании system.draw в моей службе Windows.

вот часть моего кода:

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

Исключение не только возникает в этой точке, оно также поднимается в других местах, иногда когда это включает рисование, обрезку, изменение размера, копирование изображения

Я всегда выбрасываю все использованные предметы.

Я видел эту статью об «Исключении из нехватки памяти» в system.drawing здесь

и хотя он очень похож на мой случай, он отличается, поскольку мои данные тестирования представляют собой повторяющуюся цепочку из 40 изображений, поэтому, если в одном из них есть проблема, она должна появиться быстро с первого цикла.

Я видел упомянутое ограничение здесь

он говорит, что мы не должны использовать system.drawing в Win / Web-сервисах.

ОК, мне нужно использовать его с Windows-сервисом для массовой обработки изображений, какие есть альтернативы?

Ответы [ 4 ]

1 голос
/ 26 января 2010

Объект 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 - это означает, что изображение не анализируется дважды, что должно сэкономить дополнительные ресурсы.

0 голосов
/ 01 февраля 2010

Это может быть неактуально, но ...

У меня были проблемы при работе с растровыми изображениями в C ++, при получении ошибок нехватки ресурсов из низкоуровневых оконных API. Кажется, это происходит из-за того, что куча внутренних ресурсов Windows не может обрабатывать / выделять битовые карты / битовые разделы, когда рисование выполняется с помощью битовых битов и т. П.

Не знаю, может ли что-то подобное внизу цепочки отключить библиотеки dotnet. Где-то в MSDN есть инструмент, который устанавливает драйвер устройства и может использоваться для проверки различных куч рабочего стола (не знаю, как это может относиться к сервисам.) Я думаю (с тех пор, как я его использовал), он показывает проценты / доступно - хотя это может быть некоторым индикатором, я подозреваю, что фрагментация этих областей может также привести к ошибкам - к сожалению, я не смог полностью устранить свои проблемы, но этот инструмент может помочь вам диагностировать ваши. (Похоже, инструмент можно назвать «dheapmon».)

0 голосов
/ 26 января 2010

Вы используете слишком много памяти слишком быстро и, вероятно, не освобождаете ее как можно скорее.

Вам необходимо реорганизовать код, чтобы он был более консервативным с вашими ресурсами, и убедитесь, что вы не держитесь за большие объекты дольше, чем нужно, и что вы избавляетесь от своих IDisposables в самое ближайшее время.

Этот процесс не прост, и на этом форуме нельзя ответить полностью.

0 голосов
/ 26 января 2010

Почему вы клонируете изображение? В вашем примере вы читаете данные из файла, а затем создаете копию. Для создания исключения из нехватки памяти в службе с высокой пропускной способностью объекта не требуется много времени.

Вы можете просто сделать это:

var img = Image.FromFile(ImagePath);
...