Android and running OOM with free heap space left

I have an app running OOM with plenty of free heap space free and available to grow on a stock Galaxy S3. The app runs fine on other devices.

Knowing that in traditional Java this can be caused by being OOM within the permanent generation space, I tried looking into how Dalvik handles this, but couldn't find anything definitive. Androids SDK seems to be missing both MemoryUsage and ManagementFactory, so I can't get them as you would in Java.

I'm trying to find out if Android has a permanent generation space, can I inspect its contents, how can I get the size and free, does Dalvik handle what goes into this space different than JVM, etc.

Also open to other ideas if this space doesn't exist or it's not likely.

A bit of info on the app. The S3 that is running OOM is running 4.1.2. The app uses roughly 12-25 MBs of heap with the max heap size available being around 45MBs. It has a lot of local resource images, and lazy loads many more later on. I'm .recylce()ing the bitmaps. The app crashes in roughly the same spot every time. I've gave a good look at the code around the spot that crashes and I'm not seeing anything out of the ordinary. Other devices run this code just fine.


It seems to me that you're experiencing a heap fragmentation issue.

You are failing on a 1.2MB allocation in a heap that has plenty of free space. The system probably cannot find a continuous empty chunk of 1.2MB since your heap is completely fragmented, and it can't enlarge your heap further.

Theoretically, you're not supposed to worry about fragmentation issues and the automatic GC handles it for you..

Practically, I've seen more than once that giving the system GC a helping hand sometimes achieves magnificent results.

Here are some ideas to work around fragmentation issues:

  • Run System.gc() manually in strategically placed locations. Popular locations are during destruction of large objects like activity onDestroy. Other place is before large allocations like Bitmaps. Before you decode any large bitmap, add a manual GC. If you want to reduce the number of GCs later, add an manual test for problematic memory conditions by querying the various heap size functions.

  • Assist the System GC free resources faster. This will prevent your heap from becoming fragmented in the first place. Plenty of material on the net on how to do that. Some from the top of my head:

  • If you have frequent small allocations, try to adopt a memory reuse scheme like making a pool of objects, and reusing objects in the pool instead of allocating new ones. This optimization is often seen in android adapters (like view reuse in listviews)
  • Manually set variables to null when you don't need them in order to explicitly disconnect them from the reference graph and mark them for easy GC (same goes for explicitly clearing data collections)
  • Avoid immutable classes when you have plenty of operations, like concatenation of strings, use StringBuilder instead of regular String s
  • Avoid finalizers completely
  • Avoid circular references, or at least change one of them to a weak reference
  • Use weak references in general where they're needed
  • You can measure how successful you are by making sure your heap does not grow to huge sizes when you're only using a small part of it.

    Another idea is to try and make the 1.2MB allocation smaller.. By using smaller images or rescaling them during decoding.

    链接地址: http://www.djcxy.com/p/93062.html

    上一篇: 本机堆android OOM硬件加速

    下一篇: Android和运行OOM并剩下可用堆空间