2

Windows Phone 7.1 アプリケーションのメモリを保持している原因を突き止めようとしています。アプリケーションは、SkyDrive からフル解像度の画像をダウンロードします。これらの画像を Image 要素に接続し、キャンバスに表示します。私はこれでしばらく遊んでいましたが(長すぎます!)、BitmapImage.SetSource(new URI(など))を使用して悲劇的なメモリリークが発生していたため、最近コードを書き直して次のように画像を手動でダウンロードしました。今はかなり良くなりましたが、まだ漏れがあります。誰かが私のコードでそれを見つけることができるかどうか疑問に思っています。

メモリ プロファイラからの画像は次のとおりです: http://sdrv.ms/18aXLja (画像を直接投稿するには十分な評判がありません。申し訳ありません)。

呼び出しを行っているコードは次のとおりです。このコードは、画像 URL を指す WebClient インスタンスの OpenReadCompleted イベントによってトリガーされます。このコードは、ダイアグラム内のイメージ ロードごとに実行されます (つまり、正確には 56 回)。私が理解できないことは次のとおりです:-メモリストリームが閉じられた後もメモリストリームがメモリに残る理由(画像に表示されていないのは、BitmapImage.Sour のヒープに別の割り当てがあることです)。
- BinaryReader の割り当てがまだヒープにあるのはなぜですか - すべての ExpandArray の割り当てがまだヒープにあるのはなぜですか。

あなたの洞察を前もってありがとう!

 void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        App.Progress.ProgressHide();

        if (null != e.Error)
        { return; }

        int index = iCenterImage;

        if (null != e.UserState)
            index = (int) e.UserState;

        MemoryStream ms = new MemoryStream(350000);
        //MemoryStream ms = new MemoryStream(); 
        BinaryReader br = new BinaryReader(e.Result);

        int bytesRead = 0;
        int bufferLength = 4096;
        byte[] buffer = new byte[bufferLength];

        bytesRead = br.Read(buffer, 0, bufferLength);

        while(bytesRead > 0)
        {
            ms.Write(buffer, 0, bytesRead);
            bytesRead = br.Read(buffer, 0, bufferLength);
        }

        br.Close();
        br.Dispose();
        br = null;

        BitmapImage b = new BitmapImage();
        b.SetSource(ms);
        ms.Close();
        ms.Dispose();
        ms = null;


        if (iCenterImage == index)
        {
            centerImage.Source = null;
            centerImage.Source = b;
        }
        else if (iCenterImage - 1 == index)
        {
            leftImage.Source = null;
            leftImage.Source = b;

        }
        else if (iCenterImage + 1 == index)
        {
            rightImage.Source = null;
            rightImage.Source = b;
        }
    }
4

1 に答える 1

0

ストリームとリーダーで手動で Close()/Dispose() を呼び出さないでください。ブロックを使用します。using

メモリ プロファイラーのすべてのインスタンスについて、コールスタックを確認して、そのオブジェクトを割り当てたユーザーを理解できます。

基本的に、Windows Phone の画像に既知のメモリ リークがあります (内部画像キャッシュ)。

この行を置き換えてみてください

rightImage.Source = null;

(rightImage.Source as BitmapImage).UriSource = null;
(rightImage.Source as BitmapImage).SetSource(null);
于 2013-07-10T16:13:14.767 に答える