Рекомендации по решению исключений OutOfMemory для CF - PullRequest
0 голосов
/ 08 января 2010

Мое приложение CF имеет очень настраиваемый пользовательский интерфейс, использующий множество изображений в качестве элементов пользовательского интерфейса. Пользовательский интерфейс выглядит намного более плавным, когда эти растровые изображения хранятся в памяти. Когда они загружаются по требованию, пользовательский интерфейс работает медленно, и я вижу, что кнопки появляются одна за другой, что выглядит очень плохо. В течение долгого времени это шло довольно хорошо, но недавно я обнаружил, что приложение почти использует всю память, которую оно может получить, которая составляет 32 МБ iirc. Затем я начал использовать удаленный монитор производительности, чтобы посмотреть, смогу ли я найти какие-либо чистые кабины памяти.

Как выясняется, получить полезный снимок кучи GC с помощью RPM довольно сложно: закройте, прежде чем я получу исключения из памяти, запрос моментального снимка приведет к немедленному выбрасыванию собственного исключения. Хотя мне иногда удается найти моментальный снимок GC. Я сохранил один здесь: http://files.zzattack.org/misc/ramis.gclog и скриншот здесь: http://files.zzattack.org/images/ramisgcsnapshot.png Для меня это выглядит не так уж и неприятно, безусловно, самый большой объект - это байтовый массив, содержащий мой файл ресурсов (около 3 МБ, заполненных изображениями PNG). Alltogeher, 3643304b (около 3,5 МБ) памяти используется. Эти изображения распределены по элементам пользовательского интерфейса примерно в 20 различных формах. Я не знаю, как отдельные потоки влияют на использование памяти, но одновременно работает около 5-6 потоков, из которых как минимум 4 находятся в заблокированном состоянии в 95% случаев.

В программе, когда я пытаюсь загрузить сжатый файл размером 2 МБ, я всегда получаю исключение OutOfMemoryException. Когда я вызываю GC.GetTotalMemory (false), я вижу, что я действительно пытаюсь выделить больше, чем доступно в настоящее время. Вызов GC.Collect и повторная попытка не «решают» и не откладывают мою проблему.

Я хотел бы получить несколько советов о том, как решить мою проблему. Я действительно хочу, чтобы растровые изображения находились в памяти, но, возможно, я мог бы ограничить количество слотов, доступных для растровых изображений, сохраняя в памяти только наиболее часто используемые и загружая другие по требованию. Это, вероятно, длинный путь, но, возможно, я мог бы попросить ОС зарезервировать для меня больше памяти? Я точно знаю, что приложение будет работать только на устройствах с достаточным объемом оперативной памяти. Любая помощь приветствуется, спасибо заранее.

Ответы [ 3 ]

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

Если вы используете одни и те же изображения в нескольких формах, вы должны сохранить эти растровые изображения в качестве статических переменных в классе, доступном для всех ваших форм.

public class AppBitmaps
{
  public static Bitmap LogoBitmap = new Bitmap(...);

  public static Bitmap ButtonBitmap = new Bitmap(...);
}

public class Form1
{
  public Form1()
  {
    this.Control1.Image = AppBitmaps.LogoBitmap;
  }
}

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

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

Если это снимок вашего приложения, работающего на полном наклоне, то я бы предложил:

  • Это еще одно приложение, которое работает
  • Ваше приложение превращается в неуправляемый утечка памяти
  • ОС (настроенная CE?) Имеет утечка
  • или что-то еще
0 голосов
/ 11 января 2010

«получить полезный снимок кучи GC с помощью RPM сложно» Может быть, вы можете попробовать какой-нибудь профилировщик для .NET CF, я слышал о EQATEC, если это поможет вам с потоками.

Мой подход к предотвращению ошибок OOM состоит в том, чтобы не проектировать приложение типа MDI (Multiple Document Interface), иметь только одну форму в памяти) и устанавливать в ноль все объекты после их использования (особенно «более тяжелые», такие как XMLDocument).

Также это может быть актуально: OutOfMemoryException при создании большого растрового изображения в CF.NET

...