We recently got an OutOfMemory is due to "unable to create new native thread" on our Tomcat servers. We know what the issue is - there was a bug that spawned too many Threads beyond what the ulimit on the box allowed.
What intrigues me is that, when this happened the JVM didn't dump the heap. I checked that is behavior was consistent in Java 6 and 8.
I wrote some quick Groovy PoCs to prove this behavior. So while I have used groovy here the behavior is consistent with my Servlet application (just easier for me to share a working model of the problem).
Dumps the Heap - TraditionalOOM.groovy
:
byte[] b = new byte[1000000000]
Does NOT dump the heap - ManyThreads.groovy
:
int MAX = 5000;
for (int i = 0; i < MAX; i++) {
new Thread() {
public void run() {
sleep(1000);
}
}.start();
}
Thread.activeCount();
The Java Options relevant to this issue (IMHO) are the following 2:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/somewhere
I wanted to know:
- Why does the JVM not dump the heap during an OOM (even dumping the thread dump would be helpful)?
- Is the answer the obvious one, that JVM doesn't have a thread to perform the dump?
Update
I got my answer - seems like this is the expected behavior and Oracle (or Sun) had rejected this behavior as a defect - http://bugs.java.com/bugdatabase/view_bug.do;jsessionid=74ee28dae329645479a51f6c78f2?bug_id=6784422