1

I thought checking Runtime.getRuntime().freeMemory() would do it, but the following test appears to show it is not useful:

List<Byte> listDebug = new ArrayList<Byte>();
Log.d("Free memory", String.format("%1$.2f", (float)Runtime.getRuntime().freeMemory()/(1024*1024)));
for (int i = 0; i < 100; i++) {
    try {
        listDebug.addAll(Arrays.asList(new Byte[1024 * 100]));
        Log.d("Free memory", i + ":" + String.format("%1$.2f", (float)Runtime.getRuntime().freeMemory()/(1024*1024)));
    } catch (Exception ex) {
        Log.d("Free memory", ex.getMessage());
    }
    catch (Error e)
    {
        Log.d("Free memory", e.getMessage());
    }
}

The output is the following:

03-09 03:16:11.267: D/Free memory(3860): 1.30
03-09 03:16:11.277: D/Free memory(3860): 0:1.25
03-09 03:16:11.287: D/Free memory(3860): 1:2.63
03-09 03:16:11.298: D/Free memory(3860): 2:3.86
03-09 03:16:11.298: D/Free memory(3860): 3:3.08
03-09 03:16:11.317: D/Free memory(3860): 4:4.85
03-09 03:16:11.317: D/Free memory(3860): 5:4.06
03-09 03:16:11.317: D/Free memory(3860): 6:3.28
03-09 03:16:11.367: D/Free memory(3860): 7:7.84
03-09 03:16:11.367: D/Free memory(3860): 8:7.06
03-09 03:16:11.367: D/Free memory(3860): 9:6.27
03-09 03:16:11.387: D/Free memory(3860): 10:7.84

The testing app crashes after expanding the list 11 times when freeMemory() returns the highest number. I am deeply puzzled. Is my testing code fundamentally flawed or freeMemory() is completely irrelevant to java.lang.OutOfMemoryError?

Serg
  • 2,346
  • 3
  • 29
  • 38
Hong
  • 17,643
  • 21
  • 81
  • 142

1 Answers1

2

The short answer is that it's somewhat irrelevant. The javadoc says:

Returns

the approximate amount of free memory, measured in bytes.

There are a few other questions on SO addressing this in more detail:

You could try to use the value with some margin of error (e.g., treat 85% memory usage as no free memory), but perhaps the best approach is to simply catch the OutOfMemoryError when it occurs and adjust behavior accordingly (restart the process using a less memory-intensive approach, clear other things from memory and retry the same process, skip the process entirely, alert the user, give up, etc.).

Community
  • 1
  • 1
quietmint
  • 13,885
  • 6
  • 48
  • 73
  • @Hong: Use less memory? :-) Don't try to detect and prevent the exception, instead just catch it and deal with it at that time. You should also look at the process you're conducting and adjust it to work with less data at a time or to work more efficiently to reduce the likelyhood of the error. – quietmint Mar 09 '13 at 15:52
  • I should have pointed out that I read a lot of posts about freeMemory() and OutOfMemoryError before posting this question. Catching OutOfMemoryError is not an option because it is too late to prevent the crash when OutOfMemoryError is caught. The app receives streaming data and process it. In most cases, it is only a few MB's. I thought storing a few MB data in a list would not be a problem. The only option that I can see now is serializing the data to a storage. – Hong Mar 09 '13 at 18:21