[英]Memory issues/leaks on encrypting/ decrypting large files multiple times with javax.crypto library using Sun Java Cryptography Extension (JCE)
我正在使用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
一旦分配了JVM,JVM通常不會將其回贈給OS。 而是將其保留為可用堆內存,並可以將其用於其他對象。
這意味着,在系統級別上,您只會看到內存使用量不斷增加,直到JVM停止為止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.