2009-11-05 12 views
12

システム:Windows XP SP3、.NET 3.5、4GB RAM、デュアル1.6gHzWPFがメモリから大量のBitmapSourceをリリースすることを確認しますか?

私は非常に大きなPNGをロードして(ストーリーボードアニメーションを使用して)遷移するWPFアプリケーションを持っています。これらのPNGは8190x1080の解像度です。アプリケーションが実行されると、画像とシステムメモリをキャッシュするように見えますが、メモリはゆっくりと這い上がります。最終的にはシステムを窒息させ、OutOfMemoryExceptionをスローします。私はロードするとき、私はNoneにしたBitmapSource BitmapCacheOptionを設定しています)私はアプリ

2からしたBitmapSourceオブジェクトを削除しています)

1:ここでは

は、私は現在、この問題を解決しようとする取っていステップでありますBitmapSource

3)読み込んだBitmapSourceをフリーズしています。

4)ソースを使用する画像への参照と、ソース自体への参照をすべて削除します。

5)上記の手順を実行した後、GC.Collect()を手動で呼び出してください。

WPFがこれらのイメージ用にメモリにぶら下がっている理由と、それらをロードするために使用されたメモリが適切に復元されることを保証するための解決策を見つけ出すことを願っています。

答えて

21

あなたは確かにこれに多くの作業を入れました。私は、主な問題は、BitmapCacheOption.Noneは、基になるBitmapDecoderがキャッシュされるのを妨げないということです。

あり、再び)、GC.Collect()をやって300種類のURIから300枚の小さな画像をロードし、GC.Collectを(呼び出して、このようにいくつかのトリッキーな解決策がありますが、簡単なものは簡単です:

代わりに、ウリから読み込み、単にストリームを構築し、BitmapFrameのコンストラクタに渡しで:

var source = new BitmapImage(); 
using(Stream stream = ...) 
{ 
    source.BeginInit(); 
    source.StreamSource = stream; 
    source.CacheOption = BitmapCacheOption.OnLoad; // not a mistake - see below 
    source.EndInit(); 
} 

これは動作するはずです理由は、ストリームからの読み込みが完全にキャッシュを無効にすることです。トップレベルのソースはキャッシュされていないだけでなく、内部のデコーダもキャッシュされません。

なぜBitmapCacheOption.OnLoadですか?これは直感的ではないようですが、このフラグには2つの効果があります。キャッシングが可能な場合にキャッシングが有効になり、EndInit()でロードが発生します。私たちの場合、キャッシングは不可能なので、ロードが直ちに実行されます。

明らかに、このコードをUIスレッドから実行し、BitmapSourceをフリーズして移動することができます。

BitmapCreateOptions.IgnoreImageCacheを使用しなかった理由が不思議に思うかもしれません。 IgnoreImageCacheは、URIが指定されていないキャッシュが不可能であることを除いて、イメージキャッシュを完全に無視するわけではありません。したがって、IgnoreImageCacheが設定されていても、ロードされたイメージは引き続きキャッシュに挿入されます。違いは、キャッシュ内の既存のイメージは無視されることです。

+0

BitmapSource source = new BitmapSource()がコンパイルされず、理由がわかりません。 エラー抽象クラスまたはインターフェイス 'System.Windows.Media.Imaging.BitmapSource'のインスタンスを作成できません – discorax

+0

BitmapSourceの代わりにBitmapImageを使用するとAhh..itがコンパイルされます。 これはどのように問題を引き起こしますか? :) – discorax

+0

これまでのところ、このアプローチは有望です。私はテストを続けます。 – discorax

関連する問題