Greg Donald | 8 Jun 20:39 2010
Picon

java.lang.OutOfMemoryError

I used this sort of code to make sure my bitmaps load:

    try
    {
      foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
    }
    catch( Exception e )
    {
      System.gc();
      foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
    }

In 2.2, it's now failing sometimes and my catch block no longer
catches anything.  Why would that be?

Is there a better way to avoid a java.lang.OutOfMemoryError ?

Thanks,

-- 
Greg Donald
destiney.com | gregdonald.com

--

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers <at> googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe <at> googlegroups.com
For more options, visit this group at
(Continue reading)

Stephen Eilert | 8 Jun 20:44 2010
Picon

Re: java.lang.OutOfMemoryError

On Tue, Jun 8, 2010 at 3:39 PM, Greg Donald <gdonald <at> gmail.com> wrote:
> I used this sort of code to make sure my bitmaps load:
>
>    try
>    {
>      foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
>    }
>    catch( Exception e )
>    {
>      System.gc();
>      foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
>    }
>
> In 2.2, it's now failing sometimes and my catch block no longer
> catches anything.  Why would that be?
>
> Is there a better way to avoid a java.lang.OutOfMemoryError ?
>
>

Is Dalvik such a crappy virtual machine that it can't be bothered to
run the garbage collector before spitting out an OutOfMemory
exception?

-- Stephen

Sent from my Emacs

--

-- 
You received this message because you are subscribed to the Google
(Continue reading)

Kumar Bibek | 8 Jun 20:53 2010
Picon

Re: java.lang.OutOfMemoryError

Well, each process is assigned a max heap size which varies from
device to device. And since it is an error, your catch blocks would
not be able to catch this. And also, calling gc might be able to help
you if the bitmap size exceed the allocated heap size anyway.

One workaround would be to scale your bitmap to a create a smaller
sized image which would in turn take up less space on the heap. Here
is the way to do it.

BitmapFactory.Options bmpBuffer = new BitmapFactory.Options();
bmpBuffer.inSampleSize = 4;
Bitmap bmp = BitmapFactory.decodeFile(path, bmpBuffer);

This would make your bitmaps 1/4 th of the original size and hence
would take up 1/4th space as well.

Thanks and Regards,
Kumar Bibek
http://tech-droid.blogspot.com

On Jun 8, 11:44 pm, Stephen Eilert <spedr... <at> gmail.com> wrote:
> On Tue, Jun 8, 2010 at 3:39 PM, Greg Donald <gdon... <at> gmail.com> wrote:
> > I used this sort of code to make sure my bitmaps load:
>
> >    try
> >    {
> >      foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
> >    }
> >    catch( Exception e )
> >    {
(Continue reading)

Stephen Eilert | 8 Jun 21:01 2010
Picon

Re: java.lang.OutOfMemoryError

On Tue, Jun 8, 2010 at 3:39 PM, Greg Donald <gdonald <at> gmail.com> wrote:
> I used this sort of code to make sure my bitmaps load:
>
>    try
>    {
>      foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
>    }
>    catch( Exception e )
>    {
>      System.gc();
>      foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
>    }

By the way, OutOfMemoryError is an Error, not an Exception. So catch
Error or Throwable.

-- Stephen

Sent from my Emacs

--

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers <at> googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe <at> googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

(Continue reading)

Streets Of Boston | 8 Jun 21:12 2010
Picon

Re: java.lang.OutOfMemoryError

The code above does not make sure your bitmap will load.
If there is just no memory available, then the second loading of the
bitmap will fail as well and you'll still get the OOM exception.

Your code makes a best effort to load a bitmap.
This is because the raw binary data does count to the max limit of
heap-space for the process, but the DalvikVM does not 'see' it. It
just sees the Bitmap object, the wrapper around that raw binary data.
Calling System.gc() explicitly can mitigate that, since it does clean
up the raw binary data for the bitmap. However, when there's really
not enough memory, then an OOM is unavoidable.

On Jun 8, 2:39 pm, Greg Donald <gdon... <at> gmail.com> wrote:
> I used this sort of code to make sure my bitmaps load:
>
>     try
>     {
>       foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
>     }
>     catch( Exception e )
>     {
>       System.gc();
>       foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
>     }
>
> In 2.2, it's now failing sometimes and my catch block no longer
> catches anything.  Why would that be?
>
> Is there a better way to avoid a java.lang.OutOfMemoryError ?
>
(Continue reading)

Bob Kerns | 10 Jun 03:35 2010
Picon

Re: java.lang.OutOfMemoryError

Carefully study the exception type hierarchy. Error and Exception are
distinct (and deliberately so). You are not catching OutOfMemoryError.

But catching an OutOfMemoryError and retrying is unlikely to succeed.
The VM does GC before throwing the error. It's not entirely pointless,
however -- occasionally a second GC will be able to collect something
prior GC was not able to, possibly because of running finalizers or
similar issues.  Putting the call to System.gc() there isn't a
requirement because of a deficiency in the VM, but rather a
desperation move for when in desperate straits.

It is quite likely that if that GC call helps, you're doomed to have
another OutOfMemoryError soon, that you won't recover from.

I'm NOT arguing against doing it, just putting it into context. It's
survival mode programming.

On Jun 8, 11:39 am, Greg Donald <gdon... <at> gmail.com> wrote:
> I used this sort of code to make sure my bitmaps load:
>
>     try
>     {
>       foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
>     }
>     catch( Exception e )
>     {
>       System.gc();
>       foo = BitmapFactory.decodeResource( resources, R.drawable.foo );
>     }
>
(Continue reading)

Greg Donald | 10 Jun 03:44 2010
Picon

Re: Re: java.lang.OutOfMemoryError

On Wed, Jun 9, 2010 at 9:35 PM, Bob Kerns <rwk <at> acm.org> wrote:
> Carefully study the exception type hierarchy. Error and Exception are
> distinct (and deliberately so). You are not catching OutOfMemoryError.

That's what Stephen said, but thanks all the same.

-- 
Greg Donald
destiney.com | gregdonald.com

--

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers <at> googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe <at> googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Streets Of Boston | 10 Jun 05:18 2010
Picon

Re: java.lang.OutOfMemoryError

For Bitmaps, calling System.gc() can help quite a bit.
The DalvikVM does not 'see' the raw binary data held by a Bitmap. The
process may be getting close to out-of-memory while the DalvikVM
thinks there is plenty.... the DalvikVM does not call a garbage
collection when needed.

When an allocation happens and the process runs out of memory...
kablooi.

Calling System.gc() makes sure that the garbage collection is run and
finalizers of de-referenced Bitmap instance are run so that the raw
binary data can be released.

In my experience, it is actually more 'effective' to call System.gc()
just before you start allocating a big Bitmap, causing finalizers to
run of Bitmaps that then clear/release 'hidden' raw binary data. This
cleans up the process-memory beforehand, not after the fact (after an
OOM-error).

On Jun 9, 9:35 pm, Bob Kerns <r... <at> acm.org> wrote:
> Carefully study the exception type hierarchy. Error and Exception are
> distinct (and deliberately so). You are not catching OutOfMemoryError.
>
> But catching an OutOfMemoryError and retrying is unlikely to succeed.
> The VM does GC before throwing the error. It's not entirely pointless,
> however -- occasionally a second GC will be able to collect something
> prior GC was not able to, possibly because of running finalizers or
> similar issues.  Putting the call to System.gc() there isn't a
> requirement because of a deficiency in the VM, but rather a
> desperation move for when in desperate straits.
(Continue reading)

Bob Kerns | 10 Jun 13:18 2010
Picon

Re: java.lang.OutOfMemoryError

What I was trying to get at is that if you're relying on System.gc(),
you're skating on the edge, memory-wise, tweaking the exact behavior
of the GC.

I didn't mean to suggest it's not helpful; I've followed with interest
your reports of your experience. But I'd characterize calling
System.gc() as an optimization hack, not a workaround for a system
problem.

By all means, do the extra GC. It can make the difference between a
useful and useless app.

I was really responding to Stephen's comment:
"Is Dalvik such a crappy virtual machine that it can't be bothered to
run the garbage collector before spitting out an OutOfMemory
exception? "

To which the answer is, "no, detects it when it runs the GC. But
sometimes in special cases, an extra GC can free up memory that the
first one couldn't".

Could DalvicVM handle bitmaps better? Yes. But I wouldn't call it a
"crappy VM", and it runs the GC before failing.

On Jun 9, 8:18 pm, Streets Of Boston <flyingdutc... <at> gmail.com> wrote:
> For Bitmaps, calling System.gc() can help quite a bit.
> The DalvikVM does not 'see' the raw binary data held by a Bitmap. The
> process may be getting close to out-of-memory while the DalvikVM
> thinks there is plenty.... the DalvikVM does not call a garbage
> collection when needed.
(Continue reading)

Stephen Eilert | 10 Jun 19:42 2010
Picon

Re: Re: java.lang.OutOfMemoryError

On Thu, Jun 10, 2010 at 8:18 AM, Bob Kerns <rwk <at> acm.org> wrote:
> What I was trying to get at is that if you're relying on System.gc(),
> you're skating on the edge, memory-wise, tweaking the exact behavior
> of the GC.
>
> I didn't mean to suggest it's not helpful; I've followed with interest
> your reports of your experience. But I'd characterize calling
> System.gc() as an optimization hack, not a workaround for a system
> problem.
>
> By all means, do the extra GC. It can make the difference between a
> useful and useless app.
>
> I was really responding to Stephen's comment:
> "Is Dalvik such a crappy virtual machine that it can't be bothered to
> run the garbage collector before spitting out an OutOfMemory
> exception? "
>
> To which the answer is, "no, detects it when it runs the GC. But
> sometimes in special cases, an extra GC can free up memory that the
> first one couldn't".
>
> Could DalvicVM handle bitmaps better? Yes. But I wouldn't call it a
> "crappy VM", and it runs the GC before failing.
>

And that was the whole point. In fact, the posted algorithm could try
to get into a loop, running the GC and trying to load the bitmap
again, until it succeeded (not likely) or the VM crashed and it would
be equally misguided. I was specifically objecting to that hopeful GC
(Continue reading)


Gmane