Android 当应用程序';她的记忆保持稳定

Android 当应用程序';她的记忆保持稳定,android,memory-leaks,memory-management,bouncycastle,out-of-memory,Android,Memory Leaks,Memory Management,Bouncycastle,Out Of Memory,即使运行时报告它正在使用的内存量几乎保持不变,Android也会耗尽内存并重新启动应用程序 当Android手机的应用程序使用的内存量几乎保持不变时,它怎么会耗尽内存呢 下面的代码行返回一个4到5 MB之间的几乎恒定值,但Android的应用程序管理器显示,运行中的应用程序每次迭代泄漏大约1 MB,过了一段时间,Android开始关闭进程,因为内存不足 (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())

即使运行时报告它正在使用的内存量几乎保持不变,Android也会耗尽内存并重新启动应用程序

当Android手机的应用程序使用的内存量几乎保持不变时,它怎么会耗尽内存呢

下面的代码行返回一个4到5 MB之间的几乎恒定值,但Android的应用程序管理器显示,运行中的应用程序每次迭代泄漏大约1 MB,过了一段时间,Android开始关闭进程,因为内存不足

(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())
当我使用Eclipse的内存分析器工具查看HPROF或在Android的堆工具中查看堆时,我会看到类似的结果。我也没有看到Android的分配跟踪器中分配了大量内存

因此,我面临的主要问题是: 1) 应用程序中报告的内存和android报告的内存如何不同步? 2) 在测试代码中,我将完全相信那些让我通过内存泄漏的指针。(我很乐意提供完整的测试代码。)

//这是该案例的摘录。
导入es.vocali.util.AESCrypt;
导入java.io.ByteArrayInputStream;
导入java.io.ByteArrayOutputStream;
...  
字节[]数据=获取数据(1兆字节);
AESCrypt AESCrypt=新的AESCrypt(密码);
ByteArrayOutputStream BAS=新的ByteArrayOutputStream(1兆字节+1千字节);
//每次迭代大约泄漏1兆字节
对于(int i=0;i<加密的数量;i++){
ByteArrayInputStream bais=新的ByteArrayInputStream(数据);
加密(2,bais,baos);
bais.close();
bais=null;
重置();
}

泄漏发生在对es.vocali.util.AESCrypt.encrypt(版本、InputStream、OutputStream)的调用中。我通过对线路进行注释并确保泄漏停止,从而证实了这一点。我认为泄漏与InputStream有关,因为泄漏的大小与InputStream的大小大致相同,并且泄漏的大小随InputStream的大小而变化。我尝试了几个没有解释泄漏的测试。改变输出流不会改变泄漏的大小。无论是创建新的AESCrypt对象还是重用现有的AESCrypt对象,都不能解释泄漏的原因。通过使用包重命名强制Android使用我的BouncyCastle副本,不会影响泄漏。试图强制垃圾收集不会影响泄漏。我没有解释的一件有趣的事情是,分配跟踪器在org.apache.harmony.*包中似乎有很多对象是在bouncycastle内部调用之后生成的。如果有人对自己运行测试感兴趣,我很乐意提供测试类或完整的eclipse项目(包括JAR在内,只有几兆字节。)他们还有一个Android项目,可以在手机上运行。测试也有一个主要方法,可以从命令行运行,以防您想要比较两者。这是关于我看到很多数组对象被创建,所以我测试了System.arraycopy,这不是问题。泄漏发生在对es.vocali.util.AESCry的调用中pt.encrypt(版本、输入流、输出流)。我通过注释该行并看到泄漏停止来确认这一点。我认为泄漏与输入流有关,因为泄漏的大小与输入流的大小大致相同,并且泄漏的大小随输入流的大小而变化。我尝试了几项没有解释泄漏的测试。改变输出流不会改变泄漏的大小。无论是创建新的AESCrypt对象还是重用现有的AESCrypt对象都不会导致泄漏。通过使用包重命名强制Android使用我的BouncyCastle副本不会影响泄漏。尝试强制垃圾收集不会影响泄漏。有一件有趣的事情我没有解释分配跟踪器似乎在org.apache.harmony.*包中创建了许多对象,这些对象是bouncycastle内部调用后生成的。如果有人对自己运行测试感兴趣,我很乐意提供测试类或完整的eclipse项目(包括JAR在内的只有几兆字节)他们还有一个Android项目,可以在手机上运行。测试也有一个主要方法,可以从命令行运行,以防你想比较两者。这是关于我看到很多数组对象被创建,所以我测试了System.arraycopy,这不是问题所在。
//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();  
}