Что ж, это мой первый набег в память для профилирования приложения .NET (я уже выполнил настройку процессора), и здесь я немного наткнулся на стену.
У меня есть представление в моем приложении, которое загружает 40 изображений (максимум) на страницу, каждое из которых занимает около 3 МБ.Максимальное количество страниц - 10. Поскольку я не хочу хранить в памяти одновременно 400 изображений или 1,2 ГБ, я устанавливаю для каждого изображения значение NULL при изменении страницы.
Теперь сначалаЯ подумал, что я просто должен иметь несвежие ссылки на эти изображения.Я скачал профилировщик ANTS (отличный инструмент BTW) и провел несколько тестов.График времени жизни объекта говорит мне, что у меня нет никаких ссылок на эти изображения, кроме единственной ссылки в родительском классе (что по замыслу также подтверждено тщательным прочесыванием моего кода):
Родительский класс SlideViewModelBase
навсегда остается в кэше, но свойство MacroImage
устанавливается равным нулю при изменении страницы.Я не вижу никаких признаков того, что эти объекты должны храниться дольше, чем ожидалось.
Затем я взглянул на кучу больших объектов и использование памяти в целом.После просмотра трех страниц изображений у меня выделено 691,9 МБ неуправляемой памяти и 442,3 МБ на LOH.System.Byte[]
, который происходит от моего System.Drawing.Bitmap
в BitmapImage
преобразования, занимает почти все пространство LOH.Вот мой код конверсии:
public static BitmapSource ToBmpSrc( this Bitmap b )
{
var bi = new BitmapImage();
var ms = new MemoryStream();
bi.CacheOption = BitmapCacheOption.OnLoad;
b.Save( ms, ImageFormat.Bmp );
ms.Position = 0;
bi.BeginInit();
ms.Seek( 0, SeekOrigin.Begin );
bi.StreamSource = ms;
bi.EndInit();
return bi;
}
Мне трудно найти, куда идет вся эта неуправляемая память.Сначала я заподозрил System.Drawing.Bitmap
объекты, но ANTS не показывает их слипание, и я также провел тест, в котором я был абсолютно уверен, что все они были уничтожены, и это не имело никакого значения.Поэтому я еще не выяснил, откуда взялась вся эта неуправляемая память.
Мои две текущие теории:
- фрагментация LOH.Если я отойду от постраничного представления и нажму пару кнопок, будет восстановлена половина из ~ 1,5 ГБ.Все еще слишком много, но, тем не менее, интересно.
- Какая-то странная вещь, связанная с WPF.Мы используем привязку данных для отображения этих изображений, и я не являюсь экспертом во всех подробностях того, как работают эти элементы управления WPF.
Если у кого-то есть какие-либо теории или советы по профилированию, я был бы очень признателен(конечно) мы в сжатые сроки, и я немного карабкаюсь, чтобы завершить эту последнюю часть и работать.Я думаю, что я был избалован отслеживанием утечек памяти в C ++ ... кто бы мог подумать?
Если вам нужна дополнительная информация или вы хотите, чтобы я попробовал что-то еще, спросите.Извините за настенный текст, я постарался сделать его максимально сжатым.