Ну, это мой первый набег на профилирование .NET-приложения (настройка процессора, которую я сделал), и я нахожу здесь немного стены.
У меня есть представление в моем приложении, которое загружает 40 изображений (макс.) на страницу, каждый из которых работает около ~ 3 МБ. Максимальное количество страниц - 10. Видя, что я не хочу сохранять 400 изображений или 1,2 ГБ в памяти сразу, я устанавливаю каждое изображение равным нулю при изменении страницы.
Теперь, сначала я подумал, что у меня должны быть просто устаревшие ссылки на эти образы. Я загрузил профилировщик ANTS (отличный инструмент BTW) и провел несколько тестов. График жизни объекта говорит мне, что у меня нет ссылок на эти изображения, отличные от одиночной ссылки в родительском классе (который по дизайну, также подтвержденный тщательным расчетом через мой код):
Родительский класс SlideViewModelBase
всегда хранится в кеше, но свойство MacroImage
имеет значение null, когда страница изменена. Я не вижу никаких признаков того, что эти объекты должны храниться дольше, чем ожидалось.
Далее я рассмотрел кучу больших объектов и использование памяти в целом. После просмотра трех страниц изображений у меня есть 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 работают.
Если у кого-то есть какие-либо теории или советы по профилированию, я был бы чрезвычайно благодарен, поскольку (конечно) мы находимся в сжатом сроке, и я немного борюсь за то, чтобы эта заключительная часть была выполнена и работала. Я думаю, что я был испорчен отслеживанием утечек памяти на С++... кто бы подумал?
Если вам нужна дополнительная информация или я хотел бы попробовать что-то еще, пожалуйста, спросите. Извините за текст стены здесь, я постарался сделать его максимально сжатым.