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);
}
}
The actual stack trace is
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) {
}
Which then fails with
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.
Thanks !!!
One Oracle java command line flag named -XshowSettings may help you understand what is going on.
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
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)
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With