5
votes

I seem to be having some big memory consumption issues. When I first load my wpf application which contains a gridview and an observablecollection the app is around 10mb.

When I click on an item in the gridview it opens another window which contains an image control which gets passed a base64 string that I then convert into a BitmapImage

The application then jumps up to around 123mb from 10mb. The original image size is 64k but all my stored images are base64 strings that I convert back to byte[] then into a BitmapImage. Yes I mean to do this.

When I close the window none of the ram gets release. I've even tried calling GC.

I use the following code to turn the base64 image into

var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.None;
bitmapImage.StreamSource = new SIO.MemoryStream(imageBytes);
bitmapImage.EndInit();
return bitmapImage;

That then gets assigned to Image.Source

2
This sounds like a job for profiling.Daniel Mann
Do you see any difference if you change the CacheOption to BimapCacheOption.OnLoad? Also check that you are not hanging onto a copy of the imageBytes.Nathan

2 Answers

2
votes

Below are some tips and guesses, however if you used a memory profiler you would be able see what is taking up the memory. (e.g. the CLR profiler, also VS 2012 ad 2013 come in-built memory profile tools, and other commercial ones: .NET Memory Profiling Tools)


  • Why do you specify CacheOption BitmapCacheOption.None from here that says:

Do not create a memory store. All requests for the image are filled directly by the image file.

Instead you could use OnLoad:

Caches the entire image into memory at load time. All requests for image data are filled from the memory store.

Which I read as: if you are displaying the image in many locations they share the same underlying memory. So if you are showing the same image in more than one place that would certainly be preferable.

  • Another tip found in the comments of an example here:

To save significant application memory, set the DecodePixelWidth or
DecodePixelHeight of the BitmapImage value of the image source to the desired height and width of the rendered image. If you don't do this, the application will cache the image as though it were rendered as its normal size rather then just the size that is displayed.

  • Why are you using base64 strings, why not use binary data, i.e. byte[]s? How many copies of each string do you hold a reference to?
0
votes

agreed BitMap doesnt release its memmory (tried and got tired with the memmory leak) . however try this link

Read the last comment may be this workaround might solve the problem