java.lang.OutOfMemoryError:写入outputstream时的Java堆空间

时间:2018-04-23 15:02:28

标签: java out-of-memory outputstream

我正在尝试通过传递文件流,生成的流和包含有关加密类型信息的密码对象来加密文件。这是我尝试过的:

private void processFile(Cipher cipher,InputStream inputStream, OutputStream outputStream){
   byte[] tempInputBuffer = new byte[1024];
   int len;
   try {
        while ((len = inputStream.read(tempInputBuffer)) != -1) {
            byte[] tempOutputBuffer = cipher.update(tempInputBuffer, 0, len);
            if ( tempOutputBuffer != null ) outputStream.write(tempOutputBuffer);
        }
        byte[] obuf = cipher.doFinal();
        if ( obuf != null ) outputStream.write(obuf);
        }catch (IOException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();    
        }catch (Exception e) {
            e.printStackTrace();        
        }
    }

这是我调用processFile的函数

public ByteArrayOutputStream encryptFile( InputStream fileStream, PublicKey publicKey ) throws EmprisException {

        ByteArrayOutputStream encryptedFileStream = null;
        KeyGenerator keyGenerator;
        try {

            //generate AES key
            keyGenerator = KeyGenerator.getInstance(FileUploadDownloadConstants.AES_ALGORITHM);
            keyGenerator.init(128);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] initializationVector = new byte[16];
            SecureRandom srandom = new SecureRandom();
            srandom.nextBytes(initializationVector);
            IvParameterSpec ivSpec = new IvParameterSpec(initializationVector);

            //encrypting the aes key using rsa public key and adding it to a file
            encryptedFileStream = new ByteArrayOutputStream();
            Cipher cipherRSA = Cipher.getInstance(FileUploadDownloadConstants.RSA_TRANSFORMATION);
            cipherRSA.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] secretKeyBytes = cipherRSA.doFinal(secretKey.getEncoded());
            encryptedFileStream.write(secretKeyBytes);
            encryptedFileStream.write(initializationVector);

            //call processFile to encrypt the file
            Cipher cipherAES = Cipher.getInstance(FileUploadDownloadConstants.AES_TRANSFORMATION);
            cipherAES.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
            processFile(cipherAES, fileStream, encryptedFileStream);
            encryptedFileStream.close();
            logger.logExiting(METHOD_NAME);
            return encryptedFileStream;             
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

这是我得到的堆栈跟踪:

java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3236)
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
    at java.io.OutputStream.write(OutputStream.java:75)

我在行if ( tempOutputBuffer != null ) outputStream.write(tempOutputBuffer);

中遇到内存不足错误

写输出流的方式有什么问题吗? 当我尝试使用大约15 Mb的较大文件时会发生这种情况。 非常感谢您的帮助和提前感谢。

1 个答案:

答案 0 :(得分:0)

您是否尝试过设置JVM的最小堆大小?请参阅此相关问题:

What are the Xms and Xmx parameters when starting JVMs?

您的示例的默认值可能太低。