1

Recently, when running our application, we met an out of memory exception.

This is the heap dump right before the exception happened

Heap
 def new generation   total 1572864K, used 366283K [0x00000006b0000000, 0x000000071aaa0000, 0x000000071aaa0000)
  eden space 1398144K, 13% used [0x00000006b0000000, 0x00000006bbb12d40, 0x0000000705560000)
  from space 174720K, 100% used [0x0000000710000000, 0x000000071aaa0000, 0x000000071aaa0000)
  to   space 174720K,   0% used [0x0000000705560000, 0x0000000705560000, 0x0000000710000000)

 tenured generation   total 3495296K, used 2658714K [0x000000071aaa0000, 0x00000007f0000000, 0x00000007f0000000)
  the space 3495296K,  76% used [0x000000071aaa0000, 0x00000007bcf06ba8, 0x00000007bcf06c00, 0x00000007f0000000)

 compacting perm gen  total 42048K, used 41778K [0x00000007f0000000, 0x00000007f2910000, 0x0000000800000000)
  the space 42048K,    99% used [0x00000007f0000000, 0x00000007f28ccb80, 0x00000007f28ccc00, 0x00000007f2910000)

No shared spaces configured.

It looks like old gen was almost full (76%). I assume when it finally reaches 100% OOM happens. However, it looks like eden is only at 13%.

Can someone explain why OOM happens even if there is still some space in young gen?

zapl
  • 63,179
  • 10
  • 123
  • 154
Thomas Liu
  • 21
  • 3
  • Because there wasn't enough free memory to allocate the amount of space being requested. Percentages have nothing to do with it. @HNA If that was true in any meaningful sense the JVM wouldn't start, but haven't you heard of virtual memory? – user207421 Nov 25 '15 at 19:23
  • I'm pretty sure our application only allocate small variables one by one. so OOM in the need of large chunks of memory wouldn't happen. virtual memory -- yes. I'm actually curious why OOM happens when young gen is still 16% – Thomas Liu Nov 25 '15 at 19:29
  • 1
    Are you sure it wasn't perm gen? http://stackoverflow.com/questions/88235/dealing-with-java-lang-outofmemoryerror-permgen-space-error it's at 99% full / 270k free Edit: ah no, it seems permgen isn't reporting it's actual max there: http://stackoverflow.com/questions/15611423/what-do-the-compacting-perm-gen-values-represent and 40M isn't that much compared to 1.5G heap. – zapl Nov 25 '15 at 19:38
  • you should paste the exception itself. – the8472 Nov 25 '15 at 21:39

1 Answers1

8

There is a dozen of different reasons why JVM may throw OutOfMemoryError, including

  • Java heap space: when trying to allocate an object or an array larger than maximum continuous free block in either of heap generations;
  • GC overhead limit exceeded: when the proportion of time JVM spends doing garbage collection becomes too high (see GCTimeLimit, GCHeapFreeLimit);
  • PermGen space (before Java 8) or Metaspace (since Java 8): when the amount of class metadata exceeds MaxPermSize or MaxMetaspaceSize;
  • Requested array size exceeds VM limit: when trying to allocate an array with length larger than Integer.MAX_VALUE - 2;
  • Unable to create new native thread: when reaching the OS limit of user processes (see ulimit -u) or when there is not enough virtual memory to reserve space for thread stack;
  • Direct buffer memory: when the size of all direct ByteBuffers exceeds MaxDirectMemorySize or when there is no virtual memory available to satisfy direct buffer allocation;
  • When JVM cannot allocate memory for its internal structures, either because run out of available virtual memory or because certain OS limit reached (e.g. maximum number of memory map areas);
  • When JNI code failed to allocate some native resource;
  • Etc. Not to mention that an application can throw OutOfMemoryError itself at any time just because a developer decides so.

To find out what is the reason of your particular error, you should at least look at the error message, the stacktrace and GC logs.

apangin
  • 92,924
  • 10
  • 193
  • 247