У меня проблема с утечкой памяти в моем приложении, которое загружает большое количество изображений. Я довольно плохо знаком с C # и думал, что мои дни утечки памяти прошли. Я не могу понять проблему - может быть, я использую некоторые неуправляемые модули, с которыми я не справляюсь правильно?
Чтобы проиллюстрировать мою проблему, я упростил суть причины проблемы и перенес ее в чистый проект. Обратите внимание, что это весь глупый код, который не отражает оригинальное приложение, из которого он получен. В тестовом приложении у меня есть 2 кнопки, запускающие два события.
Кнопка 1 - Создать: установка объекта в текстовом формате. Это загрузит изображения и сохранит их, установив объект в DataContext:
var imgPath = @"C:\some_fixed_path\img.jpg";
DataContext = new SillyImageLoader(imgPath);
Кнопка 2 - Очистка. Насколько я понимаю, если я отпущу ссылку, содержащую SillyImageLoader, которая снова содержит изображения, то она будет удалена. Я также явно запускаю сборку мусора, чтобы сразу увидеть объем памяти после удаления ссылки.
DataContext = null;
System.GC.Collect();
При тестировании я загружаю изображение JPEG размером 974 КБ. Хранение 30 растровых представлений этого увеличивает использование памяти моего приложения с ~ 18 МБ до ~ 562 МБ. Хорошо. Но когда я нажимаю кнопку очистки, память падает только до ~ 292 МБ. Если я повторю Create + CleanUp, у меня останется еще ~ 250 МБ памяти. Очевидно, что-то кто-то все еще держит.
Вот код SillyImageLoader:
namespace MemoryLeakTest
{
using System;
using System.Drawing;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
public class SillyImageLoader
{
private BitmapSource[] _images;
public SillyImageLoader(string path)
{
DummyLoad(path);
}
private void DummyLoad(string path)
{
const int numberOfCopies = 30;
_images = new BitmapSource[numberOfCopies];
for (int i = 0; i < numberOfCopies; i++)
{
_images[i] = LoadImage(path);
}
}
private static BitmapSource LoadImage(string path)
{
using (var bmp = new Bitmap(path))
{
return Imaging.CreateBitmapSourceFromHBitmap(
bmp.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
}
}
}
Есть идеи? Проблема, кажется, с BitmapSource. Держа только Bitmap, утечка памяти отсутствует. Я использую BitmapSource, чтобы установить это свойство Source для Image. Должен ли я сделать это по-другому? Если так - я все равно хотел бы узнать ответ утечки памяти.
Спасибо.