How to empty or clear heap memory dynamically in my code

unkown picture unkown · Mar 21, 2012 · Viewed 19.5k times · Source

In my application i am using simple gallery and the coverflow both i have my coverflow image gallery on image clicked in coverflow i am redirected to next activity that contents full screen gallery and i can even scroll my fullscreen gallery ; but when i put more amount of image or high resolution images in my app it get force closed due to Bitmap size exceeds VM budget

so i want to clear heap memory every time i finish my cover flow and gallery so i can load any amount or any resolution image in my app so if any one can help me out ... How to clear/empty heap memory every time when i finish my activity dynamically in my code? i have already tried recycle and System.gc method

Answer

Jeffrey Blattman picture Jeffrey Blattman · Mar 21, 2012

You can't "clear the heap". the VM will do that automatically when your objects are no longer referenced.

That being said, bitmaps are a tough thing in android. There's limited memory, and when an image is decoded into a bitmap it can take up a lot more memory than the compressed image format itself.

There's no easy answer to your solution. Even if you do everything correctly, you may simply be running out of memory. That being said, here are some tips:

  1. Use Bitmap.release(). bitmaps are special in that they are allocated on the native stack (as opposed to VM) heap. The javadocs are a little fuzzy, saying that you don't normally need to call this, but in my experience this "clue" to the VM that you are done with the memory backing the bitmap is important. EDIT: As of Android 3.0 (API level 11), the pixel data is stored on the Dalvik heap along with the associated bitmap.

  2. Load bitmaps into memory scaled. Here's a blog post on the topic. You only get 24MB heap on some devices and a high-res image could exhaust all of that when it's loaded into a bitmap object. There's no way around that, so you have to load it scaled.

  3. Don't call System.gc() as another answer said. The folks that built the GC algorithm are smarter than you and me; they know what they are doing. You will never get an OOME when there's memory that can be freed through a GC - the GC will always run before giving you an OOME.

  4. This one's obvious, but make sure you are not holding references to bitmaps when they are not needed any longer.

  5. Finally, and this one sucks, Android does not do heap compaction. Here's a SO question I posted on it some time ago, with no satisfactory answer. In a nutshell, Android never compacts the heap, so as your app keeps allocating big, or even medium size, chunks for bitmaps, you eventually wind up in a situation where, while you aren't out of memory, there's no large enough contiguous chunk of memory for your allocation, and you get OOME. The only way around this, as I wrote in my question, is to kill the app's process when the user quits. This make startup slower the next time, but it guarantees a brand new heap. Don't get me wrong, I can't possibly believe this is the right thing to do, but no one has come up with a better solution.