大量の画像をロードするアプリケーションにメモリ リークの問題があります。私は C# にかなり慣れていないので、メモリ リークの問題に悩まされていた日々は過ぎ去ったと思いました。問題がわかりません - 正しく処理されていない管理されていないモジュールを使用している可能性がありますか?
私の問題を説明するために、問題の原因の核心を単純化し、これをクリーンなプロジェクトに移動しました。これはすべて、元のアプリケーションを反映していないばかげたコードであることに注意してください。テスト アプリケーションには 2 つのボタンがあり、2 つのイベントをトリガーします。
ボタン 1 - 作成: オブジェクトを datacontext に設定します。これにより、画像が読み込まれ、オブジェクトを 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 に増加します。Ok。しかし、クリーンアップを実行すると、メモリは最大 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 にあるようです。ビットマップのみを保持すると、メモリ リークは発生しません。これを Image の Source プロパティに設定できるように BitmapSource を使用しています。これを別の方法で行う必要がありますか?もしそうなら、メモリリークの答えを知りたいです。
ありがとう。