Memory Leak in encrypt method on Android

Discussion related to AES Crypt, the file encryption software for Windows, Linux, Mac, and Java.
Post Reply
Mike
Posts: 1
Joined: Tue Sep 13, 2011 4:46 am

Memory Leak in encrypt method on Android

Post by Mike »

Calling AESCrypt.encrypt on Android 2.3.3 causes Android to run out of memory and shutdown processes even though memory use appears to be stable.

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.

Code: Select all

    (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.

Android uses bouncycastle as it's JCE provider. Are there any known issues between AESCrypt and Bouncycastle?

The following is an excerpt from the test code for illustrative purposes. The full code example is attached below. The relevant class is BouncyCastleAESCryptMemoryLeakExample. The example can be run as an Android service or from the command line if you want to compare the two. The issue was identified on Android.

Code: Select all

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();  
}
The leak occurs in the 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.

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.
Attachments
BouncyCastle_AesCrypt_MemoryLeakExample.zip
Eclipse Indigo Project (3.7) 1.6 MB Zip Compressed
(1.59 MiB) Downloaded 458 times
rjk
Posts: 3
Joined: Fri Mar 09, 2012 9:15 am

Re: Memory Leak in encrypt method on Android

Post by rjk »

Have you tried creating the ByteArrayOutputStream within the for loop?
i.e. put "ByteArrayOutputStream baos = new ByteArrayOutputStream(ONE_MEGABYTE+ONE_KILOBYTE);" inside the for loop and replace the "baos(reset)" in the for loop with "baos(close)".
Post Reply