java.lang.OutOfMemoryError:com.sun.crypto.provider.CipherCore.update中的Java堆空间

时间:2016-04-10 06:30:36

标签: java web-services file-io cryptography heap-memory

我正在开发一个Web应用程序,我需要为图像加密大约500mb的大文件。第一次代码工作正常,但之后我的服务器出错 java.lang.OutOfMemoryError:Java堆空间。我正在使用netbeans和glassfish服务器。我也增加了堆大小。

    byte j[] = key.getBytes();
    SecretKeySpec kye = new SecretKeySpec(j, "AES");
    Cipher enc = Cipher.getInstance("AES");
    enc.init(Cipher.ENCRYPT_MODE, kye);
    FileOutputStream output = new FileOutputStream("xyz.mkv");
    CipherOutputStream cos = new CipherOutputStream(output, enc);
    byte[] buf = new byte[104857600];
    int read;
    while ((read = file.read(buf)) != -1) {
        cos.write(buf, 0, read);
    }
    output.flush();
    buf = null;
    file.close();
    cos.close();

我不知道出了什么问题。请帮忙。 这是堆栈跟踪..

Warning:   StandardWrapperValve[DocEncrypt]: Servlet.service() for       
servlet DocEncrypt threw exception
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3236)
at com.sun.crypto.provider.CipherCore.update(CipherCore.java:666)
at com.sun.crypto.provider.AESCipher.engineUpdate(AESCipher.java:371)
at javax.crypto.Cipher.update(Cipher.java:1832)
at javax.crypto.CipherOutputStream.write(CipherOutputStream.java:158)

2 个答案:

答案 0 :(得分:1)

基于堆栈跟踪和源代码,看起来加密堆栈在内部分配一个缓冲区,其大小与您使用write调用写入的块的大小相同。

您选择使用非常大的缓冲区;即104,857,600字节。因此加密堆栈本身需要分配一个非常大的缓冲区。

解决方案:

  1. 您可以增加堆大小。
  2. 推荐:您可以将缓冲区大小减小到更合理的范围。我推荐1MiB或更低。 (大于此,使缓冲区变大的性能优势很小......)

答案 1 :(得分:0)

简短回答,您需要在启动应用程序时增加Java虚拟机fe的最大内存分配池:-Xmx2048m

有关详细信息,请查看this amswer