title: Can't Beat 'Out Of Memory' Exceptions
body: <p>I am developing an app with Mono for Android.</p>
  
  <p>I have been struggling with Out of memory exceptions for the last few days and am starting to lose hope!</p>
  
  <p>I have a ListView displaying anything from 200 to 600 items. These items consist of a bitmap thumbnail and some text.</p>
  
  <p>I am decoding the Bitmap asynchronously using an AsyncTask, here is the code:</p>
  
  <pre><code>public class BitmapWorkerTask : AsyncTask
      {
          private WeakReference imageViewReference;
          public string thisURL = "";
          private int sampleSize = 0;
          private int reqHeight = 0;
          private int reqWidht = 0;
  
          public BitmapWorkerTask(ImageView imageView, int pSampleSize, int pReqWidth, int pReqHeight)
          {
              //_____________________________________________________________________
              // Use a WeakReference to ensure the ImageView can be garbage collected
              imageViewReference = new WeakReference(imageView);
  
              reqHeight = pReqHeight;
              reqWidht = pReqWidth;
              sampleSize = pSampleSize;
          }
  
          protected override Java.Lang.Object DoInBackground(params Java.Lang.Object[] @params)
          {
              string strUrl = @params[0].ToString();
  
              try
              {
                  return DecodeSampleBitmapFromStream(strUrl, reqWidht, reqHeight);
              }
              catch (Exception ex)
              {
                  return null;
              }
          }
  
          protected override void OnPostExecute(Java.Lang.Object result)
          {
              base.OnPostExecute(result);
  
              if (IsCancelled)
              {
                  result = null;
                  Log.Debug("TT", "OnPostExecute - Task Cancelled");
              }
              else
              {
                  Bitmap bmpResult = result as Bitmap;
  
                  if (imageViewReference != null &amp;&amp; bmpResult != null)
                  {
                      ImageView view = imageViewReference.Target as ImageView;
  
                      if (view != null)
                      {
                          view.SetImageBitmap(bmpResult);
                      }
                  }
              }
          }
  
          public static int CalculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight)
          {
              //_____________________________
              // Raw height and width of image
              int height = options.OutHeight;
              int width = options.OutWidth;
              int inSampleSize = 1;
  
              if (height &gt; reqHeight || width &gt; reqWidth)
              {
                  if (width &gt; height)
                  {
                      inSampleSize = (int)Math.Round((float)height / (float)reqHeight);
                  }
                  else
                  {
                      inSampleSize = (int)Math.Round((float)width / (float)reqWidth);
                  }
              }
  
              return inSampleSize;
  
          }
  
          public static Bitmap DecodeSampleBitmapFromStream(string URL, int reqWidth, int reqHeight)
          {
              URL url = new URL(URL);
  
              try
              {
                  //______________________________________________________________
                  // First decode with inJustDecodeBounds=true to check dimensions
                  BitmapFactory.Options options = new BitmapFactory.Options();
                  options.InJustDecodeBounds = true;
                  BitmapFactory.DecodeStream(url.OpenConnection().InputStream, null, options);
  
                  //______________________
                  // Calculate inSampleSize
                  options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight);
  
                  //____________________________________
                  // Decode bitmap with inSampleSize set
                  options.InJustDecodeBounds = false;
                  return BitmapFactory.DecodeStream(url.OpenConnection().InputStream, null, options);
              }
              catch (Exception ex)
              {
                  return null;
              }
              finally
              {
                  url.Dispose();
              }
          }
  </code></pre>
  
  <p>I am starting this AsyncTask from the Lists GetView() function using this Method:</p>
  
  <pre><code>public void loadBitmap(string url, ImageView imageView)
          {
              if (Common.cancelPotentialWork(url, imageView))
              {
                  BitmapWorkerTask task = new BitmapWorkerTask(imageView, 2, 80,80);
  
                  AsyncDrawable asyncDrawable = new AsyncDrawable(null, null, task);
  
                  imageView.SetImageDrawable(asyncDrawable);
  
                  task.Execute(url);
              }
          }
  </code></pre>
  
  <p>Everything works as expected for a period of time, but if I continuously scroll up and down through my list I eventually start getting <code>OutOfMemoryException</code>s and the app crashes. My understanding of how the Android list works is it disposes of the <code>ListItem</code> views as they move off screen, but it feels as though this is not happening! </p>
  
  <p>It feels like all those bitmaps I am decoding as I scroll through the list are for whatever reason being held in memory? What could I be missing here that is preventing those bitmaps from being disposed of? Where could I implement a call to <code>Bitmap.Recycle()</code> to ensure the bitmaps are cleared?</p>
  
  <p>I did a test whereby I made a call to GC.Collect on every call to GetView which did seem to keep my memory usage fairly consistent, but I know this shouldn't be needed and it affects scrolling performance.</p>
  
  <p>Why when I scroll through my list without the call to <code>GC.Collect()</code> am I not seeing those garbage collection message indicating that the system is, in fact, doing routine collections?</p>
  
  <p>Any help is appreciated, I am losing the will to code!</p>