2

Android runs out of memory and restarts applications even though the amount of memory that Runtime reports that it is using remains nearly constant.

How can an Android phone run out of memory when the amount of memory that it's applications use remains nearly constant?

The following line of code returns a nearly constant value between 4 and 5 MB, but Android's App Manager shows that the running app is leaking about 1 megabyte per iteration and after a while, Android starts shutting down process because memory is low.

(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())

I see similar results when I use Eclipse's Memory Analyzer Tool to view HPROF or in Android's Heap tool to view the heap. I didn't see a huge block of memory being allocated in Android's Allocation Tracker either.

So, the big questions for me are: 1) How can the memory as reported in an app and the memory as reported by android be out of synch? 2) I'll give full credit for pointers that get me past this memory leak in the test code. (I'm happy to provide the full test code.)

//This is an excerpt from the case.
import es.vocali.util.AESCrypt;  
import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  

...  

byte[] data = getData(ONE_MEGABYTE);  
AESCrypt aesCrypt = new AESCrypt(PASSWORD);  
ByteArrayOutputStream baos = new ByteArrayOutputStream(ONE_MEGABYTE+ONE_KILOBYTE);  

//Each iteration leaks approximately ONE_MEGABYTE  
for(int i = 0; i < NUMBER_OF_ENCRYPTIONS; i++) {  
    ByteArrayInputStream bais = new ByteArrayInputStream(data);  
    aesCrypt.encrypt(2, bais, baos);  
    bais.close();  
    bais = null;  
    baos.reset();  
}
Mike
  • 501
  • 3
  • 8
  • The leak occurs in a call to es.vocali.util.AESCrypt.encrypt(version, InputStream, OutputStream). I confirmed this by commenting out the line and seeing that the leak stops. I think that the leak is related to the InputStream, because the size of the leak is roughly the same as the size of the InputStream and the size of the leak varies with the size of InputStream. – Mike Sep 12 '11 at 21:18
  • I tried several tests that did not explain the leak. Varying the OutputStream does not vary the size of the leak. Whether I create a new AESCrypt object or reuse an existing one does not account for the leak. Forcing Android to use my copy of BouncyCastle by using package renaming and does not affect the leak. Attempts to force garbage collection did not affect the leak. One interesting thing that I haven't explained is that Allocation Tracker seems to have a lot of objects being made in the org.apache.harmony.* packages after calls internal to bouncycastle. – Mike Sep 12 '11 at 21:44
  • If anyone is interested in running the tests themselves, I'd be happy to provide the test class or the full eclipse project (only a couple of megabytes including jars.) They also have an Android project so they can be run on a phone. The tests also have a main method so that they can be run from the command line in case you want to compare the two. – Mike Sep 12 '11 at 21:44
  • This talks about http://stackoverflow.com/questions/3238388/android-out-of-memory-exception-in-gallery/3238945#3238945 – Mike Sep 13 '11 at 06:02
  • I saw a lot of array objects being created, so I tested System.arraycopy and that's not the problem. – Mike Sep 21 '11 at 16:40
  • This is troubleshooting, so nobody will be able to give you a direct answer unless they've seen this issue before. What I can see is that the es.vocali code is Apache licensed, so why not link the source code and try to step through? I did not see any obvious resourse leaks, but I dit not look that carefully. What I do see is an obvious programming mistake - in.read(buffer) is not guaranteed to return BLOCK_SIZE bytes - but that seems to be unrelated. – Maarten Bodewes Dec 05 '11 at 22:12
  • Where are the array objects created? Are they linked to any specific class within harmony? – Maarten Bodewes Dec 05 '11 at 22:18
  • Thank you for the questions. The BLOCK_SIZE is handled in the way that the tests are setup. (There's a link to the full tests below.) I walked through the AESCrypt code. It looks like everything is fine until it disappears into the BouncyCastle code. (AESCrypt calls Android's default crypto which is BouncyCastle.) I posted a complete example on the AesCrypt forums. It contains everything that was required for my eclipse Indigo project. It is a tight example, so it's only 1.6 MB file including jars. http://forums.packetizer.com/viewtopic.php?f=72&t=187&p=456&hilit=bouncycastle#p456 – Mike Dec 25 '11 at 14:11

0 Answers0