Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Bitmaps and OutOfMemoryError: Best Practices needed
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  11 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Nathan  
View profile  
 More options Jun 16 2010, 1:24 am
From: Nathan <critter...@crittermap.com>
Date: Tue, 15 Jun 2010 22:24:45 -0700 (PDT)
Local: Wed, Jun 16 2010 1:24 am
Subject: Bitmaps and OutOfMemoryError: Best Practices needed
I'm running into OutOfMemoryErrors when allocating bitmaps. This is
not something I can reproduce with emulators, and has been reported by
a few beta testers with the HTC Incredible.

I'm not sure I can solve this directly, and my best hope is to follow
best practices for bitmaps and memory thereof. But looking for those
best practices based on groups archives left me with more questions
than answers. If anyone has a chapter about this in their book, I will
buy the book.

Here are the things I've mulled over so far:

1. I have a bitmap for a drawing buffer. It is about 3-4 megabytes on
some devices. This is the biggest bitmap I have, and without it, I
wouldn't be able to much of anything useful in my app.  I am assuming
that it would not be useful to use inPurgeable if this is a bitmap
that is drawn into. Is this true?

2. Next biggest in the hierarchy are some bitmaps that are about 22K
bytes and 256K unpacked.  Since I believe about 25 of these might be
used at one time, I have a cache with a size of 25.
I am careful to use BitmapFactory.Options.InPurgeable, so I believe
that could make them take only 22K each, but I don't see that as
guaranteed. Maybe they are taking 256K each, which would put me in the
danger zone.
As they are cycled out of the cache, I call bitmap.recycle(). I think
this a good practice. Is it?

3. Next are some resources with icon size 32x32 pixels.  There are
about 50 that could be used or reused. If I use code like this:

                                                Drawable s =
mCtx.getResources().getDrawable(R.drawable.symbol_icon);
Where s is a local variable to rendering. Suppose I call this 37
times.
Am I to assume that Android will do something smart like create only
one bitmap for this resource even if it is used 37 times?
Or am I to assume that Android will do something stupid like create 37
bitmaps and keep references in an obscure location that will prevent
garbage collection?
Do I need to get more access to these bitmaps and do something smart
myself?

4. Finally are some other icons used for menus and ImageButtons. Most
are declared in layout files - so I don't touch the bitmaps directly.

Can someone better informed than me comment on these assumptions? I'd
like to make my memory usage more efficient, but don't want to spend
time on things that will amount to shuffling chairs on the Titanic.

And how do I best measure this usage? Interestingly enough, I've tried
using the Allocation Tracker and it says I haven't allocated a single
bitmap. In light of the above, I don't think that's right.

Thanks in advance.

Nathan


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Romain Guy  
View profile  
 More options Jun 16 2010, 1:36 am
From: Romain Guy <romain...@android.com>
Date: Tue, 15 Jun 2010 22:36:40 -0700
Local: Wed, Jun 16 2010 1:36 am
Subject: Re: [android-developers] Bitmaps and OutOfMemoryError: Best Practices needed

>                                                Drawable s =
> mCtx.getResources().getDrawable(R.drawable.symbol_icon);
> Where s is a local variable to rendering. Suppose I call this 37
> times.
> Am I to assume that Android will do something smart like create only
> one bitmap for this resource even if it is used 37 times?

Drawables loaded from resources share as much data as possible. In
this case, the 37 instances would use the same Bitmap data.

--
Romain Guy
Android framework engineer
romain...@android.com

Note: please don't send private questions to me, as I don't have time
to provide private support.  All such questions should be posted on
public forums, where I and others can see and answer them


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
MarcoAndroid  
View profile  
 More options Jun 16 2010, 5:29 am
From: MarcoAndroid <marco...@gmail.com>
Date: Wed, 16 Jun 2010 02:29:05 -0700 (PDT)
Local: Wed, Jun 16 2010 5:29 am
Subject: Re: Bitmaps and OutOfMemoryError: Best Practices needed
1) 3-4M for one image is a lot since you have total of 16M for the
whole app! Dunno the answer to your question
2) 25*256K in bitmaps is already over 6,4M. Added to 1) makes already
over 10M! AFAIK you should only use .recycle() if you really don't
need them anymore. Unclear to me what "really don't need" means.
3) 32x32 pixels is about 204800 bytes if you count 4 bytes per pixel
4) These icons are probably not big right?

The allocation tracker didn't give enough details for me, so am using
the Eclipse Memory Analyzer Tool. Here's a pretty handy tutorial on
how to use it & detect memory leaks, maybe useful:
http://ttlnews.blogspot.com/2010/01/attacking-memory-problems-on-andr...

On 16 jun, 01:24, Nathan <critter...@crittermap.com> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Yahel  
View profile  
 More options Jun 16 2010, 6:43 am
From: Yahel <kaye...@gmail.com>
Date: Wed, 16 Jun 2010 03:43:00 -0700 (PDT)
Subject: Re: Bitmaps and OutOfMemoryError: Best Practices needed
Maybe you can tell us what the 4 mb pictures is used for.

Say if you are working on a game and it is your scrolling background,
maybe you could use tiles instead and only have smaller chunks.

I understand your question is about best practices, but maybe with a
use case scenario of these bitmap someone can come up with a better
strategy.

I take it you also set the BitmapFactory.Options.inInputShareable to
true so that BitmapFactory.Options.InPurgeable MIGHT not make a copy
of the data ?

Yahel


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Nathan  
View profile   Translate to Translated (View Original)
 More options Jun 16 2010, 12:28 pm
From: Nathan <critter...@crittermap.com>
Date: Wed, 16 Jun 2010 09:28:06 -0700 (PDT)
Local: Wed, Jun 16 2010 12:28 pm
Subject: Re: Bitmaps and OutOfMemoryError: Best Practices needed

On Jun 16, 2:29 am, MarcoAndroid <marco...@gmail.com> wrote:

> 1) 3-4M for one image is a lot since you have total of 16M for the
> whole app! Dunno the answer to your question

Yep

> 2) 25*256K in bitmaps is already over 6,4M. Added to 1) makes already
> over 10M! AFAIK you should only use .recycle() if you really don't
> need them anymore. Unclear to me what "really don't need" means.

That you can't use the bitmap object for drawing after you call
recycle. You'd have to recreate it.

> 3) 32x32 pixels is about 204800 bytes if you count 4 bytes per pixel

I was thinking 4096 bytes.

> 4) These icons are probably not big right?

No ,they are only 32x32 as well.

At one point, though, I have 50 or so icons in a gridview.

If I call:

         imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
         imageView.setImageResource(icon_id);

Does anyone know if the ImageView will create and preserve a bitmap of
the scaled up size? If so, that's bad, and I need to exert more
control.

> The allocation tracker didn't give enough details for me, so am using
> the Eclipse Memory Analyzer Tool. Here's a pretty handy tutorial on
> how to use it & detect memory leaks, maybe useful:http://ttlnews.blogspot.com/2010/01/attacking-memory-problems-on-andr...

I think that will help.

Nathan


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Nathan  
View profile  
 More options Jun 16 2010, 1:35 pm
From: Nathan <critter...@crittermap.com>
Date: Wed, 16 Jun 2010 10:35:41 -0700 (PDT)
Local: Wed, Jun 16 2010 1:35 pm
Subject: Re: Bitmaps and OutOfMemoryError: Best Practices needed

On Jun 16, 3:43 am, Yahel <kaye...@gmail.com> wrote:

> Maybe you can tell us what the 4 mb pictures is used for.

It's a screen buffer. It's not useful to me unless it covers the
entire screen - and then some because of arbitrary rotation. So it can
easily be a 908x908 image on Incredible.

> Say if you are working on a game and it is your scrolling background,
> maybe you could use tiles instead and only have smaller chunks.

That's what the 25 or so chunks in number two are. But as pointed out
here, they can be taking up even more room, albeit in smaller chunks.
I believe the buffer saves me from rendering these 25 images and
hundreds of smaller ones, plus some lines and points each time. I
won't rule out eliminating the screen buffer, but I'd have to profile
it.

> I take it you also set the BitmapFactory.Options.inInputShareable to
> true so that BitmapFactory.Options.InPurgeable MIGHT not make a copy
> of the data ?

Yes. I set both of those. On 1.6 or higher that is.

I can see that it is likely that inPurgeable is not effective enough
for my cache of images in number two. If it were, there would be 6
megabytes of bitmaps that could be purged before returning failure.
Since it is a hint, it's certainly possible that the HTC Incredible
doesn't do much for it. If that holds up under analysis, then perhaps
the best scheme to force purgeability at certain times.

Nathan


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Nathan  
View profile  
 More options Jun 16 2010, 2:44 pm
From: Nathan <critter...@crittermap.com>
Date: Wed, 16 Jun 2010 11:44:31 -0700 (PDT)
Local: Wed, Jun 16 2010 2:44 pm
Subject: Re: Bitmaps and OutOfMemoryError: Best Practices needed

I tried the Eclipse MAT tool. Really cool stuff.

Unfortunately, it appears blind to bitmaps, at least so far.

I was relieved to find out that the 4 Megabyte bitmap is only taking
up 32 bytes. ;)

The cache of 25 bitmaps was listed as the biggest suspect. But with a
retained heap of 600K, this only includes the original bytes, and
doesn't tell me if any of the uncompressed bitmaps are taking up
memory.

This is going to be a serious limitation of tools if they can't see
bitmaps, especially if bitmaps are your biggest suspects for leaks.

Romain, do you know if you can make any tool see bitmaps?

Nathan


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Romain Guy  
View profile  
 More options Jun 16 2010, 2:48 pm
From: Romain Guy <romain...@android.com>
Date: Wed, 16 Jun 2010 11:48:11 -0700
Local: Wed, Jun 16 2010 2:48 pm
Subject: Re: [android-developers] Re: Bitmaps and OutOfMemoryError: Best Practices needed
Bitmaps are allocated on the native heap but their size is counted
against the Java heap limit. You can use tools like MAT to see whether
you are leaking Bitmap objects but you can't rely on these tools to
measure the amount of memory used by those bitmaps. Thankfully, it's
very easy to figure out how much memory is used by a bitmap :)

--
Romain Guy
Android framework engineer
romain...@android.com

Note: please don't send private questions to me, as I don't have time
to provide private support.  All such questions should be posted on
public forums, where I and others can see and answer them


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Nathan  
View profile  
 More options Jun 16 2010, 3:06 pm
From: Nathan <critter...@crittermap.com>
Date: Wed, 16 Jun 2010 12:06:33 -0700 (PDT)
Local: Wed, Jun 16 2010 3:06 pm
Subject: Re: Bitmaps and OutOfMemoryError: Best Practices needed
On Jun 16, 11:48 am, Romain Guy <romain...@android.com> wrote:

> Bitmaps are allocated on the native heap but their size is counted
> against the Java heap limit. You can use tools like MAT to see whether
> you are leaking Bitmap objects but you can't rely on these tools to
> measure the amount of memory used by those bitmaps.

Too bad.

> Thankfully, it's
> very easy to figure out how much memory is used by a bitmap :)

Not true in all cases. Look at BitmapFactory.Options:

-------
public boolean inPurgeable

Since: API Level 4
If this is set to true, then the resulting bitmap will allocate its
pixels such that *they can be purged if the system needs to reclaim
memory*. In that instance, when the pixels need to be accessed again
(e.g. the bitmap is drawn, getPixels() is called), they will be
automatically re-decoded. For the re-decode to happen, the bitmap must
have access to the encoded data, either by sharing a reference to the
input or by making a copy of it. This distinction is controlled by
inInputShareable. If this is true, then the bitmap may keep a shallow
reference to the input. If this is false, then the bitmap will
explicitly make a copy of the input data, and keep that. Even if
sharing is allowed, the implementation may still decide to make a deep
copy of the input data.
---------

Unless you assume using inPurgeable is utterly useless, I can't tell
if those bitmaps are being purged when necessary.

That means that bitmap is using either 0, 29K bytes, 256k bytes.
That's quite a range.

In total, that means that this bitmap collection is using somewhere
between 600K bytes and 70000K bytes. Quite a range also.

So is inPurgeable useless or does it work?

Nathan


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Nathan  
View profile  
 More options Jun 17 2010, 5:32 pm
From: Nathan <critter...@crittermap.com>
Date: Thu, 17 Jun 2010 14:32:23 -0700 (PDT)
Local: Thurs, Jun 17 2010 5:32 pm
Subject: Re: Bitmaps and OutOfMemoryError: Best Practices needed
Still stuck here.

Can anyone answer me the question of whether inPurgeable works? By
works, I mean will the JVM go and purge all of those purgeable bitmaps
before returning an OutOfMemoryError for CreateBitmap?

Nathan


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Harry Ugol  
View profile  
 More options Jun 16 2010, 2:15 pm
From: Harry Ugol <harry.u...@gmail.com>
Date: Wed, 16 Jun 2010 11:15:43 -0700 (PDT)
Local: Wed, Jun 16 2010 2:15 pm
Subject: Re: Bitmaps and OutOfMemoryError: Best Practices needed

On Jun 15, 10:36 pm, Romain Guy <romain...@android.com> wrote:

> >                                                Drawable s =
> > mCtx.getResources().getDrawable(R.drawable.symbol_icon);
> > Where s is a local variable to rendering. Suppose I call this 37
> > times.
> > Am I to assume that Android will do something smart like create only
> > one bitmap for this resource even if it is used 37 times?

> Drawables loaded from resources share as much data as possible. In
> this case, the 37 instances would use the same Bitmap data.

Romain, are there any circumstances under which this would not be
true?  I'm maintaining an app where a large number of
OutOfMemoryErrors are occuring in the field, all of them from the same
line of code which is a call to setBackgroundResource(R.id.a-local-
drawable).  The implication seems to be that repeat executions of this
line of code result in OutOfMemoryErrors.  The stack trace is:

    BitmapFactory.java-2):-1:in
`android.graphics.BitmapFactory.nativeDecodeAsset'
    BitmapFactory.java:464:in
`android.graphics.BitmapFactory.decodeStream'
    BitmapFactory.java:340:in
`android.graphics.BitmapFactory.decodeResourceStream'
    Drawable.java:697:in
`android.graphics.drawable.Drawable.createFromResourceStream'
    Resources.java:-1:in `android.content.res.Resources.loadDrawable'
    Resources.java:580:in `android.content.res.Resources.getDrawable'
    View.java:-1:in `android.view.View.setBackgroundResource'

One possible factor that might result in new memory usage is that the
drawable is resized to fit in to the view.  In its original form it's
a 9-patch containing a color gradient, with different dimensions from
the view it's loaded into.

Any thoughts about what might be consuming additional memory in these
calls, or how to prevent it?

thanks,
-Harry


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »