Is there any way to handle Java heap space exception

I want to convert a file input stream for a large file (file is 100MB) and it throws 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);
    } 
}

      

The actual stack trace

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 tried to handle it using 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) {

        }

      

What's wrong

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 a way to handle this !!! Any inputs would be appreciated.

Thank!!!

+3


source to share


1 answer


One Oracle java command line flag named - XshowSettings can help you figure out what's going on.

On my machine (Ubuntu 12.04) with Oracle JVM 1.7.0_75, this program works fine without generating any output 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

      

To demonstrate what others have said regarding JVM heap handling, I ran it with -Xmx10m and this is what I got ( 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)

      

So basically on line 12 of TestClass, where we ask to return the entire bytearray, we start OOM because we started the JVM with a maximum of 10MB as a heap allocation.

The default maximum heap count in my case is 1.73G because the JVM ergonomics determines it based on the machine class. It might be different in your case, and hence the default is not right for you with a 100MB file.

+3


source







All Articles