-1

I am looking for solution to prevent OutOfMemory Error on Android. The most of the topics when searching for OutOfMemory is about BitMaps which I don't use. My problem is about loading a lot of data from DB to forms. I need to allow to add multiple forms in one view (Activity). But if I load too much data I finally get OutOfMemory. How can I prevent this ? How can I know that I shouldn't load more data because I will get OutOfMemory ?

light
  • 111
  • 2
  • 6

2 Answers2

0

You could display the forms in a ListView and dynamically load the appropriate data as the user scrolls via the getView of an an adapter.

How can I know that I shouldn't load more data because I will get OutOfMemory ?

In general with large amounts of data you should load as necessary, and discard when it is not displayed or unnecessary, so you need to determine these points in your application.

I have this debug function, that I used to use when I was allocating a lot of images. You can use it to see when you are running out of memory, and adapt it to stop allocating more if you want.

synchronized private void debugMemoryUsage() {
    DecimalFormat df = new DecimalFormat();
    df.setMaximumFractionDigits(2);
    df.setMinimumFractionDigits(2);
    // Native heap
    Double allocated = Double.valueOf(Debug.getNativeHeapAllocatedSize())/BYTES_PER_MB;
    Double available = Double.valueOf(Debug.getNativeHeapSize())/BYTES_PER_MB;
    Double free = Double.valueOf(Debug.getNativeHeapFreeSize())/BYTES_PER_MB;
    // Runtime 
    Double runtimeTotal = Double.valueOf(Runtime.getRuntime().totalMemory())/BYTES_PER_MB;
    Double runtimeMax = Double.valueOf(Runtime.getRuntime().maxMemory())/BYTES_PER_MB;
    Double runtimeFree = Double.valueOf(Runtime.getRuntime().freeMemory())/BYTES_PER_MB;

    Log.v(Tag.IMAGE_CACHE, "=================================");
    Log.v(Tag.IMAGE_CACHE, "NATIVE HEAP : allocated " + df.format(allocated) + "MB of " + df.format(available) + "MB (" + df.format(free) + "MB free)");
    Log.v(Tag.IMAGE_CACHE, "RUNTIME MEMORY: total : " + df.format(runtimeTotal) + "MB : vm max : " + df.format(runtimeMax)+ "MB : free : " + df.format(runtimeFree) +"MB free");
    Log.v(Tag.IMAGE_CACHE, "*********************************");
}

But from my experience these numbers are just an estimate so you should keep a cushion, so maybe simply allocate to a certain percentage of the VM max. The VM max is the maximum memory the app process can allocate and it is different from phone and can be as little as 16MB on older phones.

Emil Davtyan
  • 13,808
  • 5
  • 44
  • 66
  • Could be - however my forms are based on MVC pattern. I need controllers - which are most memory cunsuming - to be constantly loaded in memory as they are not part of view. – light Oct 09 '13 at 09:43
  • @light I have no idea what you are doing, but if you want to make it work you might need to break whatever pattern you are using and implement your own thing. – Emil Davtyan Oct 09 '13 at 09:45
  • Yeah, you are preety right the pattern should be changed however I have specific task to do and it have to be that way. But still, isn't there any Android callback telling me such things ? – light Oct 09 '13 at 10:12
  • @light Check out the code I posted from one of my projects. – Emil Davtyan Oct 09 '13 at 11:00
  • Very useful function, thanks :) If there is really no Android callback, it's the best. – light Oct 09 '13 at 12:41
0

Out of memory happens because the large image bitmap size, you can reduce this problem by scale down the viewed image for the user: check how to scale down

To prevent the memory from crash save the bitmap in SoftReference array, it will auto clear the image when reach out of memory instead of crash, before read the image check if deleted then re upload the bitmap to memory:

HashMap<String,SoftReference<Bitmap>> caschedImages;
Community
  • 1
  • 1
Alex
  • 1,068
  • 8
  • 23