Search code examples
javamemorygarbage-collectionout-of-memoryheap-memory

OutOfMemoryError before reaching the maximum of the heap space?


I am experiencing a very strange issue, which I would like to reproduce in a SSCCE, but I can't.

I am running my program in Java8 (32bits) with -Xmx1024m, this code is loading a pretty big file (120MB) into an array of bytes using a FileInputStream.

The problem is that, whereas in Java6 I had no problems, in Java8 I get OutOfMemoryError exceptions as soon as I try to load it.

I still have a lot of memory free, and I I have profiled it, and I see no problem.

If I try to extract out this problem in a SSCCE then it works.

I know that Oracle has got rid of the PermGen, but how that may be affecting my program?

I have also read that it might be related with a fragmentation problem of the heap space, but I tried to debug it, profile it, and run a GC cycle from the profiler just before allocating the memory, and it is still happening (I assume that a GC cycle would defragment the heap space)


Solution

  • I think I have found the reason. According to this bug report:

    https://bugs.openjdk.java.net/browse/JDK-6478546

    FileInputStream reserves the space directly into the native memory. It is actually worse when increasing the size of the Max heap space, since there is actually less space for native maps.

    The reason why my code works with Java8 64 bits, is precisely because I have more virtual space from Windows, and not constrained to ~1.7Gb in Windows.

    It is still not very clear to me, why the same code works in Java6. It seems that the same application uses more native space in Java8 than in Java6. Perhaps the new scheme with Metaspace changed things a bit. I am not sure.

    Interesting article about it:

    http://www.codingthearchitecture.com/2008/01/14/jvm_lies_the_outofmemory_myth.html