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

我有一个大小为32 MB的文件,我已将其从DocuShare服务器下载到DocuShare临时文件夹。我正在尝试从中读取文件内容以创建文件。我在对 base64 内容进行 URL 编码时遇到错误。当我运行一个简单的java应用程序时,我没有遇到任何异常。但是,当我在DocuShare服务中使用相同的代码来获取文档内容时,我会收到异常。HTTP Status 500 - org.glassfish.jersey.server.ContainerException: java.lang.OutOfMemoryError: Java heap space


org.glassfish.jersey.server.ContainerException: java.lang.OutOfMemoryError: Java heap space


File 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);

如何修复此错误?我需要增加我的雄猫堆大小吗?


桃花长相依
浏览 234回答 3
3回答

慕森王

有两种方法可以解决此问题。您可以增加堆大小,但 IMO 这是一个糟糕的解决方案,因为如果您收到多个并行请求或尝试处理更大的文件,则会遇到相同的问题。您可以优化算法 - 而不是在内存中存储文件的多个副本,而是可以以流方式处理它,从而在内存中保存不超过几个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就足够了

临摹微笑

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();

qq_遁去的一_1

如果您有大文件,则根据文件大小,您将始终遇到OOM错误。如果您的目标是使用Apache Commons Base64 Streams进行base64编码。https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Base64InputStream.html
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java