为了账号安全,请及时绑定邮箱和手机立即绑定

如何修复java.lang.OutOfMemoryError:Java堆空间错误?

如何修复java.lang.OutOfMemoryError:Java堆空间错误?

桃花长相依 2022-09-01 18:07:29
我有一个大小为32 MB的文件,我已将其从DocuShare服务器下载到DocuShare临时文件夹。我正在尝试从中读取文件内容以创建文件。我在对 base64 内容进行 URL 编码时遇到错误。当我运行一个简单的java应用程序时,我没有遇到任何异常。但是,当我在DocuShare服务中使用相同的代码来获取文档内容时,我会收到异常。HTTP Status 500 - org.glassfish.jersey.server.ContainerException: java.lang.OutOfMemoryError: Java heap spaceorg.glassfish.jersey.server.ContainerException: java.lang.OutOfMemoryError: Java heap spaceFile file = new File(filePath);FileInputStream fileInputStreamReader = new FileInputStream(file);byte[] bytes = new byte[(int)file.length()];fileInputStreamReader.read(bytes);String encodedBase64 = String encodedBase64 = java.util.Base64.getEncoder().encodeToString(bytes);String urlEncoded = URLEncoder.encode(encodedBase64);如何修复此错误?我需要增加我的雄猫堆大小吗?
查看完整描述

3 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

有两种方法可以解决此问题。

  1. 您可以增加堆大小,但 IMO 这是一个糟糕的解决方案,因为如果您收到多个并行请求或尝试处理更大的文件,则会遇到相同的问题。

  2. 您可以优化算法 - 而不是在内存中存储文件的多个副本,而是可以以流方式处理它,从而在内存中保存不超过几个KB:

import java.io.InputStream;

import java.io.OutputStream;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.util.Base64;


public class Launcher {

    public static void main(String[] args) throws Exception {

        final Path input = Paths.get("example");

        final Path output = Paths.get("output");


        try (InputStream in = Files.newInputStream(input); OutputStream out = Base64.getUrlEncoder().wrap(Files.newOutputStream(output))) {

            final byte[] buffer = new byte[1024 * 8];


            for (int read = in.read(buffer); read > 0; read = in.read(buffer)) {

                out.write(buffer, 0, read);

            }

        }

    }

}

PS:如果您真的需要URL编码器,则必须创建它的流媒体版本,但我认为URL安全的base64就足够了


查看完整回答
反对 回复 2022-09-01
?
临摹微笑

TA贡献1982条经验 获得超2个赞

Base64 将每个 3 个字节转换为 4 个字母。这意味着您可以以块的形式读取数据,并以与解码整个文件相同的方式对其进行解码。


试试这个:


       File file = new File(filePath);

       FileInputStream fileInputStreamReader = new FileInputStream(file);

       StringBuilder sb = new StringBuilder();

       Base64.Encoder encoder = java.util.Base64.getEncoder();

       int bufferSize = 3 * 1024; //3 mb is the size of a chunk

       byte[] bytes = new byte[bufferSize]; 

       int readSize = 0;


       while ((readSize = fileInputStreamReader.read(bytes)) == bufferSize) {

            sb.append(encoder.encodeToString(bytes));

       }


       if (readSize > 0) {

            bytes = Arrays.copyOf(bytes, readSize);

            sb.append(encoder.encodeToString(bytes) );

       }


       String encodedBase64  = sb.toString();


查看完整回答
反对 回复 2022-09-01
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

如果您有大文件,则根据文件大小,您将始终遇到OOM错误。如果您的目标是使用Apache Commons Base64 Streams进行base64编码。

https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Base64InputStream.html


查看完整回答
反对 回复 2022-09-01
  • 3 回答
  • 0 关注
  • 233 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信