使用 IOUtils.copyLarge 时出现内存不足错误 java 堆空间。我该如何解决这个问题?

问题描述 投票:0回答:1

我有一个在 kubernetes 上运行的应用程序(Springboot api),并且我有一个带有

cpu:200m
memory:8Gi
的单个实例。我的jvm参数是:
_JAVA_OPTIONS: -Xmx7G -Xms7G
我的目标是将一个或多个大小在 30Mb1Gb 之间的文件从一个 s3 存储桶复制到另一个具有预先签名的 url。

当我使用 1 GB 文件并行调用我的 api 超过 2 次时,出现

java.lang.OutOfMemoryError: Java heap space
错误。

这是我的代码:

public ResponseEntity<String> transferData(Config config) throws IOException {

    var inputUrl = config.getInputdUrl();
    var outputUrl = config.getOutputdUrl();


    var uploadConnection = uploader.getUploadConnection(outputUrl);

    try (var inputStream = downloader.getDownloadConnection(inputUrl); 
         var outputStream = uploadConnection.getOutputStream()) {

        IOUtils.copyLarge(inputStream, outputStream);

        var resp = uploadConnection.getResponseCode();

        return ResponseEntity
                .status(HttpStatus.OK)
                .body("Transfer done with response:" + resp);
    } catch (IOException ioe) {
        return ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("An  error occurred while transferring data : " + ioe);
    }

}

getUploadConnection
返回
HttpURLConnection
:

        var connection = (HttpURLConnection) new URL(presignedUrl).openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod(PUT.toString());
        return connection;

getDownloadConnection
返回一个
HttpURLConnection
输入流。

        HttpURLConnection connection = (HttpURLConnection) new URL(presignedUrl).openConnection();
        connection.setRequestMethod(GET.toString());
        connection.setDoOutput(true);
return connection.getInputStream();

关于我的代码和配置,我认为对内存的影响不太重要,因为我流式传输文件并且没有将其完全放入内存中。

我错过了什么?

编辑1: 我添加了

setChunkedStreamingMode
所以现在我的
getUploadConnection
返回 :

        var connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setChunkedStreamingMode(-1);
        connection.setRequestMethod(PUT.toString());
        return connection;

但是我的 s3 存储桶出现

411
错误

java spring-boot jvm inputstream java-io
1个回答
0
投票

在我的输出连接中设置

setFixedLengthStreamingMode
后,我能够传输更多文件,而不会出现
Out of memory error java heap space
问题。

我的输出连接:

var connection = (HttpURLConnection) new URL(presignedUrl).openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("PUT");
connection.setFixedLengthStreamingMode(downloadConnection.getContentLengthLong());
© www.soinside.com 2019 - 2024. All rights reserved.