有没有办法处理Java堆空间异常[重复]

Posted

技术标签:

【中文标题】有没有办法处理Java堆空间异常[重复]【英文标题】:Is there any way to handle Java heap space exception [duplicate] 【发布时间】:2015-08-04 17:42:20 【问题描述】:

我正在寻找将文件输入流转换为大文件(文件为 100MB)并且它正在抛出和 java.lang.OutOfMemoryError : Java Heap space

import java.io.FileInputStream; import java.io.IOException;

import org.apache.commons.io.IOUtils;

public class TestClass 
    public static void main(String args[]) throws IOException
    
        //Open the input and out files for the streams
        FileInputStream fileInputStream = new FileInputStream("file.pdf");
        IOUtils.toByteArray(fileInputStream);
     

实际的堆栈跟踪是

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at org.apache.commons.io.output.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:322)
    at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:463)
    at TestClass.main(TestClass.java:12)

我确实尝试过使用下面的方法来处理它

public static byte[] toByteArray(InputStream is) 
        if (is == null) 
            throw new NullPointerException("The InputStream parameter is null.");
        

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try 
            byte[] buffer = new byte[32];
            int read;
            while ((read = is.read(buffer)) != -1) 
                baos.write(buffer, 0, read);
            
            return baos.toByteArray();
         catch (IOException e) 

        

然后失败

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2786)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
    at TestClass.toByteArray(TestClass.java:25)
    at TestClass.main(TestClass.java:14)

有什么办法可以解决这个问题!!!任何意见将不胜感激。

谢谢!!!

【问题讨论】:

让你的堆更大,或者更少。 你确定byte[] buffer = new byte[32]; 是个好主意吗?我记得当我将缓冲区从 2048 更改为小于 128 时,我遇到了严重的性能问题。 使用分析器查看应用的内存使用情况。从不被垃圾收集的对象可能在它们可以被释放时被持有。如果失败,请购买更多内存芯片并将它们插入主板。 阅读这篇文章:javarevisited.blogspot.com/2011/09/… 感谢@Akash 的链接,对于其他人,我正在使用 16GB 内存的笔记本电脑,它不能比这更好。 【参考方案1】:

一个名为 -XshowSettings 的 Oracle java 命令行标志可以帮助您了解发生了什么。

在装有 Oracle JVM 1.7.0_75 的我的机器 (Ubuntu 12.04) 上,该程序运行良好,对于 100MB 文件没有产生任何所需的输出:

$ java -XshowSettings:vm -cp target/classes/:/data/home/kmhaswade/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4.jar foo.TestClass
VM settings:
    Max. Heap Size (Estimated): 1.73G
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

为了演示其他人对 JVM 处理堆空间的看法,我使用 -Xmx10m 运行它,结果如下(符合预期):

$ java -XshowSettings:vm -Xmx10m -cp target/classes/:/data/home/kmhaswade/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4.jar foo.TestClass
VM settings:
    Max. Heap Size: 10.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at org.apache.commons.io.output.ByteArrayOutputStream.needNewBuffer(ByteArrayOutputStream.java:122)
        at org.apache.commons.io.output.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
        at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1793)
        at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1769)
        at org.apache.commons.io.IOUtils.copy(IOUtils.java:1744)
        at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:462)
        at foo.TestClass.main(TestClass.java:12)

因此,基本上,在 TestClass 的第 12 行,我们要求返回整个字节数组,我们正在运行 OOM,因为我们以最大 10MB 作为堆分配启动了 JVM。

在我的例子中,默认的最大堆是 1.73G,因为 JVM 人体工程学根据机器的类来确定它。也许它在你的情况下有所不同,因此默认情况下它会因为 100MB 文件而失败。

【讨论】:

非常感谢,非常有帮助

以上是关于有没有办法处理Java堆空间异常[重复]的主要内容,如果未能解决你的问题,请参考以下文章

NETBEANS:“java.lang.OutOfMemoryError:Java 堆空间”[重复]

java.lang.OutOfMemoryError:Java 堆空间 [重复]

java.lang.OutOfMemoryError:DBeaver 中的 Java 堆空间 [重复]

java.lang.OutOfMemoryError:大型Excel文件的Java堆空间[重复]

读取大小为 330MB 的图像时发生“java.lang.OutOfMemoryError:Java 堆空间”[重复]

如何使用命令行为JAVA分配空间[重复]