Reputation: 149
I have a canvas on a window and in that canvas I have an image. This image is a System.Windows.Controls.Image and so it doesn't have / need a Dispose method.
However, when I set its Source to a new one (I have set it using a MemoryStream and with a BitmapSource, both have the same effect), its previous Source is not fully cleaned up. The memory usage goes up even when I get it to use the same image again.
After loading enough images it will crash with an out of memory exception at around 3GB. Unfortunately these are quite big images so it only takes 17 to do so.
Using Dot Memory, I can see that the "leak" is in unmanaged memory, so that would imply I'm missing a call to Dispose(), or the ImageSource is still being used in the program, but I doubt it, it's a local variable and it's not passed by reference anywhere.
I have tried forcing garbage collections and freezing the BitmapSource, but both had no effect.
Is there a way I can force it to fully clean up the previous image before I load in the next? Am I missing something? Am I misunderstanding the situation?
Here is an image showing the memory usage graph, it shows that the image is partially cleaned up when displaying a new one. The garbage collections are unforced gen 1 collections, it worries me that there are so many.
Upvotes: 0
Views: 188
Reputation: 149
The solution to this was, in the function where I was assigning the value to the Image, to pass my image in by reference.
Edit: It turns out it wasn't this, it was the garbage collector being too slow. I actually solved it by calling a method that nulled the image sources, then calling the garbage collector, then I did a MessageBox.Show() to give the GC enough time to clean up before displaying the next image.
I hope there is a better way to do this.
Edit2: I found a better way to do it. The reason the message box worked was that it updated the UI in some way which caused the canvas to be cleared. The same result can be achieved by calling Canvas.UpdateLayout()
Upvotes: 0