我正在试图弄清楚什么是为我的Windows Phone 7.1应用程序保留内存。该应用程序从SkyDrive下载全分辨率图像。它将这些图像连接到Image元素并在画布上显示它们。我已经玩了一段时间(太长了!)并且最近重新编写了我的代码以手动下载图像,因为我使用BitmapImage.SetSource(新的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;
}
}
答案 0 :(得分:0)
不要在流和阅读器上手动调用Close()/ Dispose()。 Use using
block.
对于内存分析器中的每个实例,您都可以看到callstack以了解谁分配该对象。
基本上,Windows手机图像内容中存在已知的内存泄漏(内部图像缓存)
尝试替换此行
rightImage.Source = null;
与
(rightImage.Source as BitmapImage).UriSource = null;
(rightImage.Source as BitmapImage).SetSource(null);