Igor Kulman
Igor Kulman

Reputation: 16361

Memory not being relieved when setting BitmapImage to null

I have a collections of objects, each object contains a BitmapImage. I have this collection bound to a FlipView. When user flips a page in he FlipView, the BitmapInmage of the selected object gets loaded from ApplicationData and I set the BitmapImage of the previous object to null to relieve the memory. The problem is, that the memory never gets relieved and the app crashes after some time of flipping. When I look at the collection, only the actual item has its BitmapImage set, all the others have it as null. So how do I relieve the memory?

The way I load the images:

StorageFile s = await ApplicationData.Current.LocalFolder.GetFileAsync(localFilename);
BitmapImage bitmapImage = new BitmapImage();
using (var stream = await s.OpenAsync(FileAccessMode.Read))
{                    
    bitmapImage.SetSource(stream);
}                
return bitmapImage;

Edit: I think the problem may be the way I load the Image, I guess the file stream does not get freed

Upvotes: 2

Views: 2516

Answers (5)

William Bradley
William Bradley

Reputation: 533

If you are using x:Bindings in UWP, you may find a similar issue, however, if you run Bindings.Update() after clearing out your classes (Say your image is in a class, held in an observable collection), first run .Clear() on that ObservableCollection, then Bindings.Update(), then you will find that your will regain free space.

Upvotes: 0

Jeffrey Harmon
Jeffrey Harmon

Reputation: 2437

What worked for me was setting the UriSource property to null before setting the object itself to null.

Upvotes: 1

Walt Ritscher
Walt Ritscher

Reputation: 7037

I ran into a similar issue with Windows Phone 7 applications.

One trick that worked for me was removing the image from the parent element.

grid1.Children.Remove(image1);
image1 = null;

I'm not sure if this will help in your situation though.

More details about this issue from my blog post.

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062770

In .net setting something to null never does anything - GC is unrelated and happens when it chooses. Instead, check whether the image implements IDisposable: if it does, you should be calling Dispose() when you have finished with it. Moat commonly, you would do this automatically via a "using" statement:

using(var img = GetImage()) {
    // todo: some stuff involving img
}

Upvotes: -1

Matt Varblow
Matt Varblow

Reputation: 7881

If these images are using large amounts of memory then it might make sense to force Garbage Collection to free the memory. This will only work if you've removed all strong references to the memory. You can run into performance problems if you're too aggressive in forcing garbage collection, so you'll want to experiment with this. For example, you might want to force collection only after "nulling out" a few images.

You can force garbage collection using the GC.Collect method.

http://msdn.microsoft.com/en-us/library/bb384155.aspx

Upvotes: 0

Related Questions