0

I am developing a web application where I need to encrypt a big file approx 500mb to an image. First time the code works fine but after that my server gives an error java.lang.OutOfMemoryError: Java heap space. I am using netbeans and glassfish server. I have also increased the heap size.

    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();

I don't know what's going wrong.Please help. here is the stack trace..

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 Answers2

1

Based on the stacktrace and the source code, it looks like the crypto stack is internally allocating a buffer whose size is the same as the same as the block you are writing with your write call.

You have chosen to use a really large buffer; i.e. 104,857,600 bytes. So the crypto stack itself needs to allocate a very large buffer.

Solutions:

  1. You could increase the heap size.
  2. Recommended: you could reduce the buffer size to something more reasonable. I would recommend 1MiB or less. (Larger than that, the performance benefit you get from making the buffer larger is small ...)
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

Short answer, you need to increase the maximum memory allocation pool for the Java Virtual Machine fe: -Xmx2048m when you start your application.

For more details check this amswer.

Community
  • 1
  • 1
grebesche
  • 511
  • 1
  • 3
  • 14
  • Possibly. It is also possible that he could do what he is trying to do with less memory. For instance, a 100Mb buffer seems ... profligate. – Stephen C Apr 10 '16 at 06:37
  • hmm, but would using a smaller buffer change anything (memory-wise)? It would just create more smaller byte[] arrays which would end up being almost the same, right?. I don't think the GC would be fast enough to keep-up anyways. – grebesche Apr 10 '16 at 06:53
  • Of course it would. If you use a smaller buffer, that's a smaller heap node for the buffer. It is not the speed of the GC that matters. To a first approximation, it is the total size of all reachable objects that determines when you run out of space. – Stephen C Apr 10 '16 at 07:11
  • Ha! yes you are right, I just realized that the `byte[] buf` would be reused (I first though a new one would be created for each iteration... – grebesche Apr 10 '16 at 07:20
  • as @StephenC suggested, a smaller buffer size would help a lot. – grebesche Apr 10 '16 at 07:23