title: Android - recover from low memory condition
body: <p>I'm developing an application with very intense image processing where I have multiple <code>ListFragments</code> in the horizontal <code>FragmentStatePagerAdapter</code>. I aggressively employ practically every trick and suggestion I was able to find here and elsewhere. I download bitmaps and save these to SD and as soft reference memory cache. </p>
  
  <p>Nevertheless as I use the app at certain point I start seeing messages in LogCat just like one below</p>
  
  <pre><code>11-05 15:57:43.951: I/dalvikvm-heap(5449): Clamp target GC heap from 32.655MB to 32.000MB
  11-05 15:57:43.951: D/dalvikvm(5449): GC_FOR_MALLOC freed 0K, 24% free 11512K/14983K, external 17446K/17896K, paused 64ms
  11-05 15:57:44.041: D/dalvikvm(5449): GC_EXTERNAL_ALLOC freed &lt;1K, 24% free 11511K/14983K, external 17258K/17896K, paused 77ms
  </code></pre>
  
  <p>If I continue, messages above will become more urgent</p>
  
  <pre><code>11-05 16:02:09.590: D/dalvikvm(5449): GC_FOR_MALLOC freed 0K, 23% free 11872K/15239K, external 17497K/17896K, paused 71ms
  11-05 16:02:09.700: D/dalvikvm(5449): GC_EXTERNAL_ALLOC freed &lt;1K, 23% free 11872K/15239K, external 17497K/17896K, paused 84ms
  11-05 16:02:09.720: E/dalvikvm-heap(5449): 192816-byte external allocation too large for this process.
  11-05 16:02:09.800: I/dalvikvm-heap(5449): Clamp target GC heap from 33.057MB to 32.000MB
  11-05 16:02:09.800: D/dalvikvm(5449): GC_FOR_MALLOC freed 0K, 23% free 11872K/15239K, external 17497K/17896K, paused 68ms
  11-05 16:02:09.800: E/GraphicsJNI(5449): VM won't let us allocate 192816 bytes
  </code></pre>
  
  <p>And inevitably the app will crash with OutOfMemoryException
  The symptoms are classical memory leak. Yet in my <code>Fragment#onDestroy</code> method I cancel all the pending tasks, unbind and nullify the views and call Bitmap#recycle. 
  Interestingly enough, I do see GC calls in the LogCat but even if I pause for extended period the memory is never reclaimed.</p>
  
  <p>My gut feeling is that it is continuous re-reading of images from SD that causes degradation and inevitable demise</p>
  
  <p>Here's utility cleaning method I'm using trying to shake off drawables (there's more as I said to cancel pending/running tasks and empty ListView adapters)</p>
  
  <pre><code>public static void unbindDrawables(View view, final boolean agressive) {
          if (view instanceof ViewGroup) {
              for (int i = 0; i &lt; ((ViewGroup) view).getChildCount(); i++) {
                  unbindDrawables(((ViewGroup) view).getChildAt(i), agressive);
              }
              if (!AdapterView.class.isInstance(view)) {
                  ((ViewGroup) view).removeAllViews();
              }
          } else {
              Drawable bmp = view.getBackground();
              if (bmp == null &amp;&amp; ImageView.class.isInstance(view)) bmp = ((ImageView) view).getDrawable();
              if (bmp != null) {
                  bmp.setCallback(null);
                  if (agressive &amp;&amp; (TaggedDrawable.class.isInstance(bmp))) {
                      Bitmap bm = ((BitmapDrawable) bmp).getBitmap();
                      if (bm != null) {
                          if (DEBUG) Log.i(TAG, "Forcing bitmap recycle for " + bmp);
                          bm.recycle();
                          bm = null;
                          view.destroyDrawingCache();
                          view = null;
                      }
                  }
              }
          }
      }
  </code></pre>
  
  <p>Needless to say I'm seriously disturbed at this point and will greatly appreciate any suggestions </p>