2016-04-10 2 views
0

Я разрабатываю веб-приложение, где мне нужно зашифровать большой файл размером около 500 мб для изображения. В первый раз код работает нормально, но после этого мой сервер дает ошибку java.lang.OutOfMemoryError: Java heap space. Я использую сеть netbeans и glassfish. Я также увеличил размер кучи.java.lang.OutOfMemoryError: Java heap space at com.sun.crypto.provider.CipherCore.update

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) 
+1

Пожалуйста, покажите нам трассировку стека. –

+0

@StephenC Я добавил трассировку стека. –

ответ

1

Основываясь на stacktrace и исходном коде, похоже, что криптовый стек внутренне выделяет буфер, размер которого тот же, что и тот блок, который вы пишете, с вызовом write.

Вы решили использовать действительно большой буфер; т.е. 104 857 600 байт. Таким образом, сам криптовый стек должен выделять очень большой буфер.

Решения:

  1. Вы можете увеличить размер кучи.
  2. Рекомендовано: вы можете уменьшить размер буфера до более разумного. Я бы рекомендовал 1MiB или меньше. (Более того, преимущество в производительности, которое вы получаете от создания большего размера буфера ...)
+0

решает эту проблему, но как я могу улучшить производительность этого алгоритма. –

+0

Я не могу придумать более быстрый способ в Java. Шифрование дорогое. Вы можете попробовать сделать это с использованием собственных (сторонних) библиотек или автономных родных Утилиты. –

+0

Спасибо за помощь. –

0

Короткий ответ, вы должны увеличить максимальный объем пула выделения памяти для Java Virtual Machine фе: -Xmx2048m при запуске приложения.

Подробнее ... this amswer.

+0

Возможно. Возможно также, что он мог делать то, что он пытается делать с меньшим объемом памяти. Например, буфер 100 Мб кажется ... расточительным. –

+0

hmm, но использовал бы меньший буфер, чтобы изменить что-нибудь (по памяти)? Он просто создал бы более мелкие байт [] массивы, которые в итоге оказались бы почти одинаковыми, верно ?. Я не думаю, что GC будет достаточно быстрым, чтобы идти в ногу со временем. – grebesche

+0

Конечно, было бы. Если вы используете меньший буфер, это меньший узел кучи для буфера. Это не скорость GC. В первом приближении это общий размер всех достижимых объектов, который определяет, когда вы исчерпаете пространство. –

Смежные вопросы