I'm trying to figure out what is keeping memory around for my Windows Phone 7.1 application. The application downloads full resolution images from SkyDrive. It wires those images to Image elements in and displays them on a canvas. I've been playing with this for a while (way too long!) and recently re-wrote my code to manually download the images as follows since I was getting tragic memory leaks using BitmapImage.SetSource(new URI(etc.)). It's much better now, but I still have leaks. Wondering if someone can spot it in my code, much appreciated!
Here's the image from the memory profiler: http://sdrv.ms/18aXLja (not enough reputation here to post the image directly, sorry)
Here's the code that is making the calls. This code is triggered by the OpenReadCompleted event of a WebClient instance pointing at the image URL. This code runs for each Image Load in the diagram (so 56 times to be exact). What I can't figure out is:
- why the memory stream remains in memory after it is closed (what's not shown in the image is there is a separate allocation on the Heap for BitmapImage.Sour).
- Why are BinaryReader allocation still on the heap
- Why are all the ExpandArray allocations still on the heap.
Thanks in advance for your insights!
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;
}
}