0

パッケージを使用して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の反復後に観察されたメモリ使用量は増加し、その後正常に戻りませでし.

4

1 に答える 1