简体   繁体   中英

Android OutOfMemory when GC reports free memory?

So I'm looking through a log of an OOM failure where I see the following:

05-15 14:18:15.801: D/dalvikvm(5425): GC_BEFORE_OOM freed 12K, 63% free 18896K/49863K, paused 43ms, total 44ms
05-15 14:18:15.801: E/dalvikvm-heap(5425): Out of memory on a 25694224-byte allocation.
05-15 14:18:15.801: I/dalvikvm(5425): "AsyncTask #4" prio=5 tid=35 RUNNABLE
05-15 14:18:15.801: I/dalvikvm(5425):   | group="main" sCount=0 dsCount=0 obj=0x41f117e8 self=0x5db0f2c0
05-15 14:18:15.801: I/dalvikvm(5425):   | sysTid=5539 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1544307456
05-15 14:18:15.801: I/dalvikvm(5425):   | schedstat=( 0 0 0 ) utm=19 stm=2 core=0
05-15 14:18:15.801: I/dalvikvm(5425):   at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
05-15 14:18:15.801: I/dalvikvm(5425):   at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:520)

This looks weird to me. Why is there an OOM on ~25mb allocation when I have ~30mb available?

EDIT

The code goes roughly through these steps:

  1. camera.takePicture(null,null,callback)
  2. inside callback send data to AsyncTask for processing/saving
  3. AsyncTask decodes byte array into a Bitmap for further rotation
  4. bOOM!

It seems your bitmap is allocating more than the available heap size. You can always monitor your memory usage using Eclipse MAT or android studio.

I suggest you to scale down your bitmap if they are larger than required. Also use options.inJustDecodeBounds = true to ensure your app is not kicked off from memory because of bitmap allocation. try to free resources what your app is not displaying. For free memory onPause call is a good place.You should also use GC call efficiently if needed. Also you can use

Drawable drawable = imageView.getDrawable();
if (drawable instanceof BitmapDrawable) {
    BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
    Bitmap bitmap = bitmapDrawable.getBitmap();
    bitmap.recycle();
} 

to free the resource from your imageViews.

You can also set largeHeap="true". This actually force other app to out of memory . so how much heap will increase you never know. It depends on if any app was forced to get out of memory.

You have other option is create separate process so they will assign separately memory heap in your application. for this you have to use process="your process name" within activity tag.

You need to understand a few things first.

  • Android takes some time to grow the memory, and sometimes it's not fast enough. See https://stackoverflow.com/a/14462026/1390015 .
  • You need to load the bitmap into the right size. This will make your app faster and prevent consuming extra memory.
  • You need to recycle your bitmaps.

I suggest you take a look at some Android image library like Picasso[ http://square.github.io/picasso/] . It should do some of that work for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM