【问题标题】:Java Heap Space is insufficient to upload files on AWS S3Java 堆空间不足,无法在 AWS S3 上上传文件
【发布时间】:2025-11-23 14:00:02
【问题描述】:

我正在尝试使用 Java-AWS API 在 AWS S3 上上传文件。问题是我的应用程序无法上传大型文件,因为堆已达到其限制。 错误:java.lang.OutOfMemoryError: Java 堆空间

我个人认为扩展堆内存不是一个永久的解决方案,因为我必须上传高达 100 GB 的文件。我该怎么办?

这里是sn-p的代码:

        BasicAWSCredentials awsCreds = new BasicAWSCredentials(AID, Akey);
        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
        .withRegion(Regions.fromName("us-east-2"))
        .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
        .build();

        InputStream Is=file.getInputStream();

        boolean buckflag = s3Client.doesBucketExist(ABuck);
        if(buckflag != true){
           s3Client.createBucket(ABuck);
        }
        s3Client.putObject(new PutObjectRequest(ABuck, AFkey,file.getInputStream(),new ObjectMetadata() ).withCannedAcl(CannedAccessControlList.PublicRead));

【问题讨论】:

  • ObjectMetadta.setContentLength(fileLength),当 outOfMem 发生时? from javadoc: "..如果没有提供,库必须缓冲输入流的内容以便计算它。"
  • 请将您的代码添加到问题中。否则我们只能猜测,但不能真正帮助您。
  • 我已经添加了代码。 @Codo
  • @xerx593 我没有提供文件长度。我应该对代码进行哪些更改?
  • 请看我的回答 *.com/a/64263423/1704634 ,它使用 S3OutputStream 自动切换到分段上传,以防流太大。当前使用 10MB 缓冲区,但这可以配置得更小/更大。

标签: java amazon-web-services spring-boot amazon-s3


【解决方案1】:

我强烈推荐setContentLength()ObjectMetadata,因为:

..如果未提供,库将不得不缓冲输入流的内容以便计算它。

(..这会导致“足够大”文件出现 OutOfMemory。)

来源:PutObjectRequest javadoc

应用于您的代码:

 // ...
 ObjectMetadata omd = new ObjectMetadata();
 // a tiny code line, but with a "huge" information gain and memory saving!;)
 omd.setContentLength(file.length());

 s3Client.putObject(new PutObjectRequest(ABuck, AFkey, file.getInputStream(), omd).withCannedAcl(CannedAccessControlList.PublicRead));
 // ...

【讨论】:

  • 嗯,我在设置内容长度时遇到了完全相同的错误。
  • @AleksanderLech:好的,这(很好,它)意味着您可以排除“这个错误”,而问题是“代码中的其他地方”。 “OOM”的坏处:很难追踪/ce! :( ... *.com/q/37335/592355
  • “直觉猜测”:您将(x-large)文件“碰撞”到其他地方“(完全或足够大的部分)到内存中”! ...(您在 s3 之前/之后对 file 做什么?)
【解决方案2】:

您需要添加示例代码以获得正确答案。如果你在处理一个大对象,请使用 TransferManager 上传而不是使用 putObject。

【讨论】:

  • 使用 TransferManager 后仍然面临堆空间问题....我正在处理大对象。
最近更新 更多