我正在使用javax.crypto
包来加密/解密文件,但问题是一旦一个大文件(大约100到700 mb)被加密,内存就会达到70 Mb(第一次)和整个执行完成后不释放此内存。我让我的应用程序运行了几天,但这个内存不会降低。
有趣的是,如果我一次又一次地加密/解密同一个文件,内存不会上升70 Mb,但是对于前3-4次迭代,在每次迭代中释放5-8 Mb的内存,之后内存开始在块中再次增加2-5 Mb,经过几次迭代,一些内存被释放,但所有内存总是增加
加密文件的代码很简单
static Cipher c;// = Cipher.getInstance("AES/CBC/PKCS5Padding");
private static void Encrypt_File(String infile, String outFile) throws Exception
{
//String destKey = "123456";
//byte[] IV = generateRandomBytes(16);
//byte[] salt = generateRandomBytes(16);
//Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes("123456", salt, 1000);
//SecretKey key = new SecretKeySpec(rfc.getBytes(32), "AES");
SecretKey key = new SecretKeySpec(generateRandomBytes(32), "AES");
//if(c == null)
c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, key);
FileOutputStream fos = new FileOutputStream(outFile);
CipherOutputStream cos = new CipherOutputStream(fos, c);
FileInputStream fis = new FileInputStream(infile);
try
{
int len = 0;
byte[] buf = new byte[1024*128];
while((len = fis.read(buf)) != -1) {
cos.write(buf, 0, len);
//cos.flush();
}
}
finally
{
c.doFinal();
cos.flush();
cos.close();
fos.flush();
fos.close();
fis.close();
}
}
这是我在程序中看到的简单观察: 我使用的是Windows 7 64位,16 GB RAM,Intel Core 2 Duo 3.00 GHz,加密文件大小为700 MB。
Explanation Memory Usage(Shown in Windows Task Manager Private Working Set column)
When program starts 9924 K
After first iteration of encryption 81,180 K
Second Iteration 78,254 K
3 Iteration 74,614 K
4 Iteration 69,523 K
5 Iteration 72,256 K
6 Iteration 70,152 K
7 Iteration 83,327 K
8 Iteration 85,613 K
9 Iteration 95,124 K
10 Iteration 92,698 K
11 Iteration 94,670 K
我保持迭代开始进行2000次迭代,观察到相同的模式,并且在最终内存使用量为184,951 K时,在调用System.gc()
后也没有释放此内存。
可能存在的问题是CipherOutputStream
或Cipher
类是否有内存泄漏或我在这里做错了什么?
编辑看到链接(在评论中发布)后,我进行了更改,以便我可以打印JVM中的内存使用情况,即在代码中添加这些行
System.out.println(" " +i +" \t\t\t " + ConvertTOMB(Runtime.getRuntime().totalMemory()) +" \t\t "+ ConvertTOMB(Runtime.getRuntime().freeMemory()) +" \t\t "+ ConvertTOMB( Runtime.getRuntime().totalMemory() -Runtime.getRuntime().freeMemory()) );
在 1000 迭代后观察到内存使用量增加然后没有恢复正常,因为在前几次迭代中内存使用量 1-5 MB 但是在之后> 1000次迭代内存消耗从未返回单个数字,范围 25-225 MB
答案 0 :(得分:0)
一旦分配了JVM,JVM通常不会向操作系统返回内存。相反,它将它保留为自由堆内存,并可以将其用于其他对象。
这意味着,在系统级别上,您将看到内存使用量增加,直到JVM停止。