我的应用程序中存在内存泄漏问题,它会加载大量图像。我对 C# 相当陌生,并认为我的内存泄漏问题已经过去。我无法找出问题所在 - 也许我正在使用一些我没有正确处理的非托管模块?
为了说明我的问题,我简化了导致问题的核心并将其转移到一个干净的项目中。请注意,这都是愚蠢的代码,并没有反映它来自的原始应用程序。在测试应用程序中,我有 2 个按钮,触发了两个事件。
按钮 1 - 创建:将对象设置为数据上下文。这将加载图像并通过将对象设置为 DataContext 来使它们保持活动状态:
var imgPath = @"C:\some_fixed_path\img.jpg";
DataContext = new SillyImageLoader(imgPath);
按钮 2 - 清理:我的理解是,如果我放开持有 SillyImageLoader 的引用,该引用再次持有图像,那么它将被删除。我还显式地触发垃圾收集,只是为了在删除引用后立即查看内存量。
DataContext = null;
System.GC.Collect();
测试时,我正在加载 974KB 的 jpeg 图像。保存 30 个位图表示可以将我的应用程序的内存使用量从 ~18MB 提高到 ~562MB。行。但是当我点击清理时,内存只下降到~292MB。如果我重复 Create+CleanUp,我将剩下大约 250MB 的内存。所以很明显,某些东西仍然被某人持有。
这是 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 属性。我应该这样做吗?如果是这样 - 我仍然想知道内存泄漏的答案。
谢谢。