2

我试图弄清楚是什么为我的 Windows Phone 7.1 应用程序保留了内存。该应用程序从 SkyDrive 下载全分辨率图像。它将这些图像连接到 Image 元素中并将它们显示在画布上。我已经玩了一段时间了(太久了!),最近重新编写了我的代码以手动下载图像,因为我使用 BitmapImage.SetSource(new URI(etc.)) 遇到了可悲的内存泄漏。现在好多了,但我还是有泄漏。想知道是否有人可以在我的代码中发现它,非常感谢!

这是来自内存分析器的图像: 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 回答