Когда вы скрываете изображения, возможно ли, что изображение загружается снова.Т.е. вы прячете его, а скрытый остается там, и он снова добавляется позже.Следовательно, вы накапливаете огромное количество скрытых изображений?
«Утечки памяти» в приложениях .NET часто являются результатом отсутствия обнуления ссылок или удаления объекта из всех коллекций.Пока объект имеет ссылку откуда-либо, какой-либо элемент управления в коллекции элементов управления в форме или одну из ваших собственных коллекций, он будет оставаться в памяти.Я не уверен, что вы используете для показа / скрытия изображения, но, возможно, вам нужно удалить изображение и убедиться, что вы удаляете ссылки на него из всех соответствующих элементов управления.Благодаря тому, как коллекции элементов управления могут быть вложенными, было бы легко пропустить место.Вероятно, существует много дополнительных накладных расходов с элементами управления, связанными с изображениями, поэтому, если у вас есть много неиспользуемых элементов управления, скрытых, но находящихся в памяти, это может быть проблемой.
Вы говорите, что у вас есть 50 графических блоков, но выбольше изображений, чем в коллекции не отображается.Если вы загрузили их в коллекцию, то независимо от того, отображаются они или нет, они могут занимать память.
Соедините вещи, о которых следует знать.
1) Для процесса в 32-битной Windows доступно максимум 2 ГБ памяти.Есть способы настроить это на 3 ГБ на машине, но обычно вы не должны ожидать, что будет доступно более 2 ГБ.Ojn Кроме того, обычная фрагментация памяти может привести к тому, что вы получите исключения OutOfMemory, даже если вам кажется, что у вас много свободной памяти.
2) Когда вы имеете дело с коллекциями .NET, обычно они реализуются внутренне.как массивы.Массив - это непрерывный блок памяти.Поэтому, даже если у вас много свободной памяти, можно получить исключение OutOfMemory, потому что нет достаточно непрерывного блока памяти (из-за фрагментации)..NET пытается уменьшить фрейминг, но иногда это похоже на перемещение гигантского стола в переполненной комнате, это не может творить чудеса.
3), поскольку массивы не расширяются динамически, внутренне коллекция должна выделятьновый массив всякий раз, когда ему не хватает места.Обычно это удваивает размер массива каждый раз.Это свойство ".Capacity" большинства коллекций.Вы должны использовать некоторую отладку для мониторинга .Capacity и .Length коллекции.Вы будете наблюдать это удвоение каждый раз, когда коллекция достигает такого размера.Т.е. 128, 256 и т. Д.
Всякий раз, когда он удваивается, он должен выделить новый массив, а затем скопировать содержимое старого массива, прежде чем освободить старый массив.Следовательно, если у вас была коллекция с 256 (или другой степенью 2, например, 64) элементами, а затем добавлен еще один элемент, внутренне коллекция выделяет новый массив из 512 элементов, а затем копирует в него из предыдущего массива.Во время этого переходного процесса у вас есть как 512, так и 256 массивов в памяти.Таким образом, хотя вам нужно только место для 257 элементов, для добавления 257-го элемента требуется в три раза больше места (256 + 512 = 768).
Вы можете использовать трассировку стека, чтобы определить, происходит ли исключение при попыткедобавить картинку в коллекцию, поскольку именно в вызове добавляется время, когда коллекция расширяется, если это необходимо.Вы также заметите, что длина как раз перед вызовом будет иметь степень 2.
Так что, если у вас есть 512 МБ изображений, и коллекция должна быть расширена, чтобы добавить еще один, .NET должен найти пространство для выделения1 ГБ массив изображений.Таким образом, во время этого перехода коллекции, для расширения ее емкости, потребуется 1,5 ГБ ОЗУ.Для .NET будет ОЧЕНЬ ТРУДНО, чтобы найти непрерывный блок 1 ГБ оперативной памяти из-за фрагментации, даже если со всеми шагами .NET, чтобы минимизировать фрагментацию, все еще есть большой контроль.(Кто-то, вероятно, скажет, что массив ссылок намного меньше, но трудно сказать, с чем вы имеете дело.)
Решение: Если вы решите, что это является причиной вашей проблемы, то решение состоит в том, чтобы предсказать, сколько элементов вам потребуется, и заранее установить емкость массива. Поэтому, если у вас есть список изображений, то лучше сначала подсчитать количество этих изображений, а затем установить Емкость коллекции на эту сумму, а может быть, плюс на 10% больше или что-то еще. Таким образом, если у вас есть 300 предметов, вы можете установить емкость на 350. Таким образом, вместо этого вы заранее оценили емкость с небольшим свободным пространством, тогда она никогда не будет расширяться, и, таким образом, не будет испытывать 3-кратный всплеск использование памяти для расширения.
Профилировщики памяти Google .NET. Есть много профилировщиков, а также win debug, которые позволят вам увидеть детали выделения и освобождения памяти, а также фрагментации.