アプリケーションで大量の画像を読み込むメモリリークの問題があります。私はむしろC#の初心者ですし、メモリリークの問題の私の日が過去だったと思いました。私は問題を理解することができません - おそらく私は正しく処理されていないいくつかの管理されていないモジュールを使用していますか?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にあるようです。ビットマップだけを保持すると、メモリリークはありません。 BitmapSourceを使ってこれをImageのSourceプロパティに設定することができます。私はこれを違うはずか?もしそうなら、私はまだメモリリークの答えを知りたいです。
ありがとうございました。
誰が呼び出しているのですか?LoadImageから返されたBitmapSourceを破棄しますか? –
私はこれを実際にそれに基づいて答えを投稿したと思ったが、BitmapSource(私は答えを削除しました)で処分を見ることができません –
あなたはどのようにアプリケーションのメモリ使用量を監視していますか?タスクマネージャー? –