有什么办法可以处理Java堆空间异常 [英] Is there any way to handle Java heap space exception

查看:135
本文介绍了有什么办法可以处理Java堆空间异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望将文件输入流转换为大文件(文件大小为100MB),并且正在抛出java.lang.OutOfMemoryError:Java堆空间

I am looking to convert file input stream for big file (The file is of 100MB) and it is throwing and 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)

我确实尝试使用以下方法来处理它

I did tried to handle it using the below method

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)

有什么办法可以解决这个问题!!!

Is there any way we could handle this !!! Any inputs will be appreciated.

谢谢!!!

推荐答案

一个名为 -XshowSettings 的Oracle Java命令行标志

One Oracle java command line flag named -XshowSettings may help you understand what is going on.

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

On my machine (Ubuntu 12.04) with Oracle JVM 1.7.0_75, this program runs fine, producing no output as desired, for a 100MB file:

$ 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来运行它,这就是我得到的(符合预期):

To demonstrate what others have said with respect to JVM's handling of the heap space, I ran it with -Xmx10m and here's what I get (as expected):

$ 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启动了JVM作为堆分配。

Thus, basically, at the line 12 of TestClass, where we are asking for the entire bytearray to be returned, we are running OOM because we started the JVM with maximum 10MB as the heap allocation.

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

The default max heap in my case is 1.73G because JVM ergonomics determine it based on the class of the machine. Maybe it's different in your case and hence by default it fails for you with a 100MB file.

这篇关于有什么办法可以处理Java堆空间异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆