1

i have an Android app that displays alot of images, it works, the images are gatherd from an url, added to a que and gathered by 4 threads,stored in a cache and then displayed in a listview view 4 images for row, there are abot six rows at each time on the screen. There is a total of usually 90 images.

The rows(and imageviews) are always recycled, so the amount of items is always the same and i'm not initializing anything.

This seems to work quite fine, i have always an average used heap size of 13MB.

The problem i have is that at the beginning mi max heap size is quite small and i get GC messages like:

01-20 16:48:39.191: D/dalvikvm(9743): GC_FOR_ALLOC freed <1K, 31% free 12048K/17351K, paused 25ms

but the more i scroll up down the view the heap size grows more and more untile i get things like

01-20 17:02:05.339: D/dalvikvm(11730): GC_FOR_ALLOC freed 544K, 72% free 13871K/49159K, paused 35ms

as you see even if the used is the same the maximum is increased even if i never got to that limit. and the true problem is that at this point i start to get outofmemory errors.

Can someone explain me what's wrong?

Thanks!

trincot
  • 317,000
  • 35
  • 244
  • 286
Duiker101
  • 587
  • 1
  • 4
  • 19

3 Answers3

0

My guess is that your app reaches a very high peak of memory usage for a short time. It's true that on average you only use 13MB but if your heap grows to as much as 50MB, it means that momentarily you've consumed much more memory than you're thinking.

Let's try to figure out where this is happening. You've mentioned that you're using an LRU cache. This cache frees memory as soon as it fills up. My guess is that you're starting to free memory too late, and this memory isn't freed immediately - since it depends on the system GC. Whenever you're freeing some items from the cache, try to call System.gc() manually.

You've also mentioned that you're calling Bitmap.recycle(). To the best of my knowledge this is useless on Android 3+ because the native heap is no longer used for bitmaps. Since all bitmaps are on the dalvik heap, they will be freed by the GC.. You can't rush this like before unless you call System.GC() yourself.

Another idea for your source of problems is heap fragmentation. See my previous SO answer to a similar issue in this question.

Community
  • 1
  • 1
talkol
  • 12,564
  • 11
  • 54
  • 64
0

What version of Android are you using? If you're testing on pre 3.0 (ie 2.x), the byte arrays that store most of the information in Bitmaps are allocated and stored in native memory. This means that in heap dumps and in the GC notifications, you only see the small amount of memory used for pointers in Bitmaps, rather than the actual size.

For more information check out this google IO talk on memory management and detecting memory leaks: http://www.youtube.com/watch?v=_CruQY55HOk

Also I've worked on several apps doing similar things. My guess is that either your cache size is way too large, or (more likely) the images you're displaying and storing in the cache are much larger than the size you actually want. If you display a bitmap in an image view, the imageview will store the original bitmap in memory, even if it is significantly larger than what would actually fit in the view. Try resizing the images from disk to at least closer to the appropriate size before trying to display them: How do I scale a streaming bitmap in-place without reading the whole image first?

Community
  • 1
  • 1
Sam Judd
  • 7,317
  • 1
  • 38
  • 38
0

To cache my Images I use Map<String, Drawable> drawableMap. On a OutOfMemoryError I call this function:

private void cacheLeeren()
{
    int size = drawableMap.size();
    int del = (int) (size * 0.3);
    Set<String> s = drawableMap.keySet();
    for (String t : s)
    {
        if (del >= 0)
        {
            drawableMap.put(t, null);
            del--;
        }
    }
}

I think it's not the best way...but it works ;-)

PKeidel
  • 2,559
  • 1
  • 21
  • 29
  • 1
    Far better would be to use `SoftReferences` and `LinkedHashMap` in LRU mode, so you would not have to wait for a crash to have better memory consumption characteristics. – CommonsWare Jan 20 '12 at 19:16
  • It would be cool to see an example of this. Is something like koush's https://github.com/koush/UrlImageViewHelper a good example? – Ehtesh Choudhury May 21 '12 at 21:22