2013-10-09 112 views
0

我的問題是,我正在解密/加密來自不同線程的一些隨機值的字符串集,但經過很多次迭代後內存迅速增加。
我的觀察是,內存增加,因爲每個加密/解密導致新的字符串,並由於它增加了內存。
還有一點需要注意的是,我的解密/加密的字符串將具有許多相同的值作爲相同的字符串集(某些字符串可能是新的)從許多線程加密/解密,但因爲在每個加密/解密密碼函數返回字節數組並再次構成字符串,我必須使用'new String()'函數,這可能會或將會迅速增加內存。
這是我的代碼,加密/解密字符串在java中AES加密/解密字符串中的內存問題/泄漏

public static String encrypt(String key, String value) throws GeneralSecurityException 
{ 

    byte[] raw = key.getBytes(); 
    if (raw.length != 16) { 
     throw new IllegalArgumentException("Invalid key size."); 
    } 

    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16])); 
    byte[] cipherBytes= cipher.doFinal(value.getBytes()); 
    byte[] encoded = org.apache.commons.codec.binary.Base64.encodeBase64(cipherBytes); 
    return new String(encoded); 

} 

public static String decrypt(String key, String encrypted) throws GeneralSecurityException 
{ 

    byte[] raw = key.getBytes(); 
    if (raw.length != 16) { 
     throw new IllegalArgumentException("Invalid key size."); 
    } 
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16])); 
    byte[] byteDecodedText = org.apache.commons.codec.binary.Base64.decodeBase64(encrypted.getBytes()) ; 

    byte[] original = cipher.doFinal(byteDecodedText); 

    return new String(original); 
} 
+3

只要您從字節數組中提取它,就可以在'String'上調用'intern()',並刪除所有對'String'的引用。 'String'會佔用內存直到它被垃圾收集,當然,但我看不出你能做得比這更好。 –

+0

@DavidWallace它意味着我必須調用intern對新的字符串(byteDecryptedText); – dbw

+2

是的,顯然。但是無論如何你必須在某個時候調用'new String(byteDecryptedText)'。 –

回答

2

字符串實習生方法可能是要走的路。它返回字符串的標準表示形式,因此對於相同的字符串,您將只有一個實例。 所以,當你返回一個字符串,只是儘量做到:

new String(byteDecryptedText).intern(); 

通過使用新的你走出範圍後,將收集創建一個字符串的一個實例。內部對象將被返回。

+0

感謝您的回覆,但它並沒有解決問題,因爲當我們調用新的字符串(byteDecryptedText)時,堆中的新字符串已經創建 – dbw

+1

是的,它會由gc收集後,你從我認爲是好的函數返回因爲沒有提及該實例。因此,總堆大小將相應地增長,只有相應的字符串 –

+0

讓我們[在聊天中繼續討論](http://chat.stackoverflow.com/rooms/38872/discussion-between-dbw-and-david-wallace) – dbw

1

確實每次迭代都會產生新的字符串,但我不認爲這會很快地增加內存,因爲字符串所需的內存是以字節爲單位的。
根據String memory usage,您可以計算您加密或解密的字符串的大小。這可以讓你瞭解內存是否增加是由於每次形成新的String。

+1

有效的一點,現在看看問題與一些不同透視 – dbw