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!!!
source to share
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.
source to share