У меня проблема с утечкой памяти в моем приложении, которая загружает большое количество изображений. Я новичок в С#, и думал, что мои дни проблемы с утечкой памяти прошли. Я не могу понять проблему - может быть, я использую некоторые неуправляемые модули, которые я неправильно обрабатываю?
Чтобы проиллюстрировать мою проблему, я упростил суть проблемы, которая вызвала проблему, и перенесла ее в чистый проект. Обратите внимание, что это все глупый код, который не отражает оригинальное приложение, из которого он пришел. В тестовом приложении у меня есть две кнопки, запускающие два события.
Кнопка 1 - Создать: установка объекта в datacontext. Это загрузит изображения и сохранит их, установив объект в DataContext:
var imgPath = @"C:\some_fixed_path\img.jpg";
DataContext = new SillyImageLoader(imgPath);
Кнопка 2 - CleanUp: Я понимаю, что если я отпущу ссылку, содержащую 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. Удерживая только битмап, утечки памяти нет. Я использую BitmapSource, чтобы иметь возможность установить это свойство Source для изображения. Должен ли я делать это по-другому? Если так - я все равно хотел бы узнать ответ на утечку памяти.
Спасибо.