Android Bitmaps and Memory Leaks

I wanted to share some info that I have been learning about in my latest project. It seems that Android has an interesting way of memory management for Bitmaps. Drawables seem to act normal and get cleaned up with the garbage collector, but Bitmaps are apparently not in the normal application heap. This causes problems… for me anyway. There is an awesome article about it here if you want to learn more about it and how to find memory leaks in general.

Basically the solution to this problem is to manually recycle any Bitmaps you create once you are done using them. This seems pretty simple because you can basically call recycle() on all your bitmaps in the onDestroy() hook in your Activity. However, most of the time you have a separate thread running that is using these image resources. If you recycle your bitmaps in the Activity, there is no guarantee that your background thread won’t come searching for these resources before it dies.

My solution: I created an “ImageManager” class.

class ImageManager {
    private HashMap<Integer, Bitmap> mBitmaps;
    private HashMap<Integer, Drawable> mDrawables;
    private Context mContext;

    private boolean mActive = true;

    public ImageManager(Context c) {
        mBitmaps = new HashMap<Integer, Bitmap>();
        mDrawables = new HashMap<Integer, Drawable>();
        mContext = c;

    // We need to share and cache resources between objects to save on memory.
    public Bitmap getBitmap(int resource) {
        if (mActive) {
            if (!mBitmaps.containsKey(resource)) {
                    BitmapFactory.decodeResource(mContext.getResources(), resource));
            return mBitmaps.get(resource);
        return null;

    public Drawable getDrawable(int resource) {
        if (mActive) {
            if (!mDrawables.containsKey(resource)) {
                mDrawables.put(resource, mContext.getResources().getDrawable(resource));
            return mDrawables.get(resource);
        return null;

    public void recycleBitmaps() {
        Iterator itr = mBitmaps.entrySet().iterator();
        while (itr.hasNext()) {
            Map.Entry e = (Map.Entry);
            ((Bitmap) e.getValue()).recycle();

    public ImageManager setActive(boolean b) {
        mActive = b;
        return this;

    public boolean isActive() {
        return mActive;

This does two things: first, it makes it easy to recycle all your bitmaps and keep track of when you have recycled them to shut down your app, and second, It enables you to share repeated resources.  In my app, I have images that I use many instances of. Previously I would instantiate a new Drawable or Bitmap for these using up memory for a resource I already had in memory.  When you get a resource from the ImageManager, because it keys on the drawable ID, it checks to see if it is already available before loading it again.

It also makes it a little easier to get an image.  the ImageManager object you create will have to be passed to every object you want to use it, but when it’s available just call im.getDrawable(R.drawable.whatever) to get your Drawable.

You will still have the problem of the background thread trying to access assets after they are recycled.  To avoid this you will have to either check every time to see if the ImageManager is still active, or (the lazy way) catch the NullPointerException it throws when it tries to draw.

22 Responses to “Android Bitmaps and Memory Leaks”

  1. LM says:

    Thank you for the post. I’ve not tried yet but this is what i wanted

  2. Cory Trese says:

    It seems like there is a code error here with “mGame”

  3. Nate says:

    You’re right. There were a couple references outside code that I missed. I’ve updated the code so that you can just pass your application’s Context to it on construction. I haven’t tested it yet, but it should make it more independent.

  4. Mike says:

    Hi Nate,

    Excellent class thanks for sharing. Could you elaborate more on how to “check every time to see if the ImageManager is still active”. I’m not getting that.



  5. Mike says:

    Hi Nate,

    That was easy, what if you need to reference the drawable by ImageView Id?

  6. Mike says:

    Ok now how to avoid this

    03-19 11:28:51.701: WARN/dalvikvm(14369): threadid=1: thread exiting with uncaught exception (group=0×40015560)
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): FATAL EXCEPTION: main
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): java.lang.NullPointerException
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at$3(
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at$1.handleMessage(
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at android.os.Handler.dispatchMessage(
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at android.os.Looper.loop(
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at java.lang.reflect.Method.invokeNative(Native Method)
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at java.lang.reflect.Method.invoke(
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at$
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at
    03-19 11:28:51.721: ERROR/AndroidRuntime(14369): at dalvik.system.NativeStart.main(Native Method)

  7. Mike says:

    This is how I’m calling it

    final ImageView animDialog = (ImageView) myDialog.findViewById(;


  8. Heartache says:

    Thank you very much for your guidance.

  9. shubham says:

    hello Nate, Thanks for sharing your knowledge, In my same app seen is something difference.
    I am drawing multi Bitmap images over the canvas and after an limit i got OutOfMemory Exception.
    Here how i can free memory for non-top images . Because Bitmap images stl showing on Canvas.

    pls suggest ..thanks again

  10. shubham says:

    hello ,

    I am drawing multi Bitmap images over the canvas , nw when I invalid an single view so all views got invalidate(means redraw again).
    Is it possible to invalid only single view .

    pls suggest me .


  11. Cory Trese says:

    Thanks again, this code has been really helpful. My memory management issues are greatly reduced =)

  12. Venu says:


    Can you please give me an example of how to reuse the bitmaps and drwables set in hashmap. No need to give entire program, just give me a snippet of code to understand the logic behind it.


  13. Eugen says:

    Hello Nate!

    I’ve implemented something almost the same to your’s, but I stil have problems with accessing recycled bitmaps by children of ListView or GridView. any suggestion how to avoid such kind of problems?
    PS. In adapter i get bitmaps from ImageManager, when i leave the activity i recycle all of them. I’ve tried to set adapter = null, but it makes the list to disappear (it’s logic) and it’s does not look nice. Any suggestions will be appreciated.

    Thanks in advance!

  14. Raul says:

    Please, can you give me an example on how to use this class from an Activity? I’ve spend A LOT of time on this and still have the outofmemory …


  15. anon says:

    Caching Drawables also carries the potential of memory leaks unless the cache and drawables dies with the activity or an activity state change, or you specifically clear it’s references to views and/or context.

  16. Nate says:

    Yeah, that’s why there’s the recycleBitmaps() method. It’s my understanding that as long as you recycle your bitmaps in your onDestroy(), everything else will be taken care of with the GC.

  17. test1 says:

    Thanks so much for including me in your list of fabulous bloggers!

  18. [...] 本文链接: Bitmaps图片泄露问题 版权所有: 非特殊声明均为本站原创文章,转载请注明出处:开发者 订阅更新: 您可以通过RSS订阅我们的内容更新 [...]

  19. [...] taking up valuable application memory. If LruCache can’t resolve the problem you can try this:ImageManager ,in the class ImageManager, it has a method recycleBitmaps. This entry was posted in android [...]

  20. game mobile says:

    Hello There. I discovered your weblog the use of msn. This is a really neatly written article. I will make sure to bookmark it and return to read more of your helpful information. Thank you for the post. I’ll definitely return.

  21. 楽天 ショルダーバッグ ポロシャツ 長袖 レディース

  22. Spot on with this write-up, I truly believe that this site needs a lot more attention.
    I’ll probably be returning to read through more, thanks for the information!

Leave a Reply