What are the different kinds of OutOfMemoryError in Java, and what causes each one?
The error message names the resource that ran out, and that is the fastest way to know which problem you have.
Java heap space means the heap is exhausted. Either the live data set genuinely exceeds the heap — in which case the answer is more memory or a smaller working set — or something is being retained that should not be, which is a leak. This is the variant you will meet most often.
Metaspace means the class metadata area is exhausted. It happens when the program loads classes continuously, usually because a class loader is being recreated and each one loads its own copies of the classes. It is a native memory problem, so it is not fixed by raising the heap size.
Unable to create new native thread means the process cannot get another thread from the operating system. The cause is usually the number of threads rather than their size — a thread-per-request design with no bound, or a platform limit on the number of threads per process.
Direct buffer memory means the direct byte buffers allocated outside the heap have exhausted the limit. It usually shows up just after a garbage collection, because the buffers are only reclaimed then.
GC overhead limit exceeded means the collector spent nearly all of its time collecting and reclaimed almost nothing — the classic sign of a heap that is too small for the live data set, so almost everything is live.
And Requested array size exceeds VM limit means you asked for an array bigger than the JVM will allow, usually because of an integer overflow in a size calculation — a multiplication that wrapped around and produced a negative number that became a huge unsigned value.