Forum Xamarin Xamarin.Android

Disposing of Bitmaps Properly

KevinSkreiKevinSkrei USMember ✭✭

I've been reading many blog posts/forums on the issue of Android bitmaps. In my app, I load a moderate amount of Bitmaps which are placed in ImageView's. I am using the methods described in the documentation about "Loading large bitmaps efficiently". When I load each of my bitmaps I can see the native heap increase in size by < 1MB. Not a huge problem until I have to load quite a few.

  1. How do you know if I have a memory leak? I can see the heap size increasing while loading the bitmaps and even after I dispose of all of the resources (ie. bitmap, imageview etc) in the OnDestroy() and Finish() the activity, the heap size never goes down. The problem is i'm not sure when the GC is supposed to reclaim the memory? Is it only when the OS needs more resources? Or does it happen periodically? If so, how often? Even after I finish the activity and wait awhile, I keep checking the heap size and it never decreases.

  2. How do you properly dispose of a bitmap? Is simply wrapping the bitmap in a using statement like I have below good enough? Or do I have to look out for some lingering reference to a Context or something?

Basically, I have a custom view (derives from LinearLayout) which in turns has an ImageView. The user can take a photo or load it from the gallery and when finished, the imageview is populated with the image they took/selected. I have pasted some code below. Does anyone have any ideas where/if there is a problem?

//DecodeImageFromFile uses the InSampleSize to reduce the size
using(Bitmap bitmap = DecodeImageFromFile(ImageFilePath, _Global.DeviceWidth, _Global.DeviceHeight))
{
     if (bitmap != null)
    {

     _ImageSelected = new ImageView(Context) {LayoutParameters = Utils.GeneratetLinearLayoutParams(5,5,10,10)};
     _ImageSelected.SetImageBitmap(bitmap);
     _ImageSelected.SetAdjustViewBounds(true);
         Context.RunOnUiThread(() => _Layout.AddView(_ImageSelected));

     ImageAdded = true;
     _Global.AppLayer.LogMemory();

    }
}

and In the OnDestroy() of the activity, I go through each custom view I created and call the method on the custom view that does this

if(_ImageSelected != null)
{
      _Layout.RemoveView(_ImageSelected);
  if (_ImageSelected.Drawable != null) {
    _ImageSelected.Drawable.Dispose ();
  }
  _ImageSelected.SetImageBitmap(null);
  _ImageSelected.Dispose();
  _ImageSelected = null;
}

Posts

  • alienpaperalienpaper GBMember ✭✭

    I'm doing something similar to your code, but also keep a ref to the bitmap so I can call Bitmap.Recycle. This works for me.

    private void FreeImageMemory ()
    {
        _image.SetImageBitmap (null);
        _bitmap.Recycle ();
        _bitmap.Dispose ();
        _bitmap = null;
    }
    
  • DWestyDWesty USMember ✭✭

    Just to cover the bases in the long long ago bitmaps needed to be recycled. Part of this has to do with how Android originally implemented Bitmaps the memory that was associated with them was hidden from Dalvik.

    As far as how the GC works.. In both Dalvik and Mono the GC runs when you need more memory. How and when this happens will depend on the allocations. You shouldnt need to recycle bitmaps. Also if you are holding a reference to the bit map the GC wont come and reclaim the memory during run time.

  • HakanLindhHakanLindh USMember

    Wrote a small program that I ran on my Ice Cream Sandwich phone. It holds on to a bitmap connected to an image view. Clicking a button loads another bitmap and sets it to both the variable and the image view - in theory this should free the old bitmap's memory. It will not, unless I explicitly call Recycle on the bitmap. It will first then be garbage collected. If I don't call Recycle, the memory just keeps on clicking up.

  • khanzzirfankhanzzirfan NZMember ✭✭

    @alienpaper That answer works for me brilliant. It clearly reduces the memory allocation. Thank you.

    I followed the article http://developer.xamarin.com/recipes/android/resources/general/load_large_bitmaps_efficiently/
    but realized that using statement doesn't free heap memory. It still keep object in memory. Hence the above article is not helpful in releasing memory management. I think some one need to revisit the article.

Sign In or Register to comment.