Memory Leak in encrypt method on Android
Posted: Tue Sep 13, 2011 5:23 am
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.
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.
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.
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())
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();
}
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.