2011-12-02 2 views
11

まず、BitmapImageを、WindowImageコントロールにロードします。 第2に、私はImageコントロールで作業してからWindowを閉じます。BitmapImageが不要になった後にメモリを解放するには?

私は分にそれを2〜3回行うと、ウィンドウが閉じられたときに画像が戻ってアンロードする必要はありませんので、私の記憶は非常に迅速にいっぱいになります。

それでは、どのようにメモリを解放するために、手動でImage.SourceコントロールからBitmapImageをアンロードするには?

答えて

16

私はあなたが探しているソリューションはhttp://www.ridgesolutions.ie/index.php/2012/02/03/net-wpf-bitmapimage-file-locking/であると信じています。私の場合は、作成後にファイルを削除する方法を見つけようとしていましたが、両方の問題の解決策であるようです。

は、メモリを解放しません:

var bitmap = new BitmapImage(new Uri(imageFilePath)); 

は、メモリを解放し、ファイルを削除することができます:

var bitmap = new BitmapImage(); 
var stream = File.OpenRead(imageFilePath); 
bitmap.BeginInit(); 
bitmap.CacheOption = BitmapCacheOption.OnLoad; 
bitmap.StreamSource = stream; 
bitmap.EndInit(); 
stream.Close(); 
stream.Dispose(); 

必要に応じて、また、BitmapImageの凍結:

bitmap.Freeze(); 
+0

はい、それは昔の私のために働いた。 – AgentFire

+0

偉大な答え、ありがとう。私を助けてくれました。 – MDDDC

-1

あなたは、ウィンドウのClosedイベントで画像にDispose()を呼び出すことができます。さまざまなキャッシングオプションを使用してメモリフットプリントを最適化することも可能かもしれません。

編集:あなたは廃棄する()を呼び出すことはできません

、代わりに、あなたはBitmapCacheOption.Noneを検討するかもしれません。イメージはディスクから直接読み取られ、メモリにはキャッシュされません。

+0

新しいBitmapImage(新しいUri(リンク)、新しいRequestCachePolicy(RequestCacheLevel.NoCacheNoStore))を使用しようとしましたが、違いはありません。メモリはまだ使用中です。 – AgentFire

0

のBitmapImageオブジェクトがもはや参照されるように、あなたは、nullにオブジェクトを設定することはできません。 このような状況では、GCはリソースを解放する必要があります。 GC.Collectに電話することができますが、あまりにも頻繁に使用するとパフォーマンスに影響する可能性があります。

+0

'GC.Collect()'は 'BitmapImage'への参照をnullにしてもリソースを解放しません。 – AgentFire

+0

リファレンスチェーンはどのように見えますか?それは 'Image-> BitmapImage-> MemoryStream-> filestream->実際のバイト数のメモリのようなものですか?'あなたは正しいオブジェクトをヌル参照する必要があります。そうでなければまだメモリを使用しています。 – abhinav

+0

これは次のようになります。 'Image.Source = new BitmapImage(新しいUri(リンク)); ' – AgentFire

1

私の状況では、ビットマップキャッシングが問題だったようです。

Bitmap bitmap = new Bitmap(); 

using(var stream = new FileStream(...)) 
{ 
    bitmap.BeginInit(); 
    bitmap.CacheOption = BitmapCacheOption.OnLoad; 
    bitmap.StreamSource = stream; 
    bitmap.EndInit(); 
} 

bitmap.Freeze(); 
image.Source = bitmap; 

継続的にだけ手動でガベージコレクションは本当に助けていなかったを強制的に、メモリを築いimage.Source同じように置き換える:私は以前にこのようなビットマップをロードしました。

代わりに、キャッシングを無効にしてストリームを使用すると(画像が表示されるまでストリームを開いたままにする必要があります)、手作業によるガベージコレクションと組み合わされるとメモリが増えなくなります。

Stream mediaStream; 

void DisposeMediaStream() 
{ 
    if (mediaStream != null) 
    { 
     mediaStream.Close(); 
     mediaStream.Dispose(); 
     mediaStream = null; 
     GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true); 
    } 
} 

void Update() 
{ 
    DisposeMediaStream(); 

    var bitmap = new BitmapImage(); 
    mediaStream = new FileStream(...); 

    bitmap.BeginInit(); 
    bitmap.CacheOption = BitmapCacheOption.None; 
    bitmap.StreamSource = mediaStream; 
    bitmap.EndInit(); 

    bitmap.Freeze(); 
    ControlImage.Source = bitmap; 
} 

この方法では、(Windowsフォトビューアーのような)たくさんの画像を循環させることができ、メモリは低いままです。画像が実際にレンダリングされると、ストリームは開いたままである必要はありません。

関連する問題