Artifactory is a Maven repository manager that does a lot of really useful things, such as cache maven artifacts (which saves external bandwidth and makes downloads faster) and stores our own artifacts (such as 3rd party software that can’t be on a public maven repository for licensing reasons). I recently upgraded from Artifactory 1.2 to 2.0.0, which was pretty painless.
The problems appeared the next day, when the application died with “java.lang.OutOfMemoryError: unable to create new native thread.” I tried a lot of things, but what worked was reducing the stack size. The JVM has an interesting implementation, the design of which I don’t completely understand, but the implication is that the more memory is allocated for the heap (not necessarily used by the heap), the less memory available in the stack, and since threads are made from the stack, in practice this means more “memory” in the heap sense (which is usually what people talk about) results in less threads being able to run concurrently.
To reduce the stack size, add “-Xss64kb” to the JVM options. I suggest you start with 64k, try the application, then if it doesn’t work (it will fail with a Java.lang.StackOverFlowError), increase the stack to 128k, then 256k, and so on. The default stack size is 8192k so there’s a wide range to test.
Also, on Linux, you’ll need to set the Linux thread stack size to the same value as the JVM stack size to get full benefits. To do that, use “ulimit -s <size in kb>”. In my case, Artifactory works great with a 128kb stack, so I used “-Xss128kb” for the JVM options and “ulimit -s 128” to set the Linux stack size. Note that the stack size applies per user, so you have to modify the init script, or edit /etc/security/limits.conf (on Debian/Ubuntu at least).
Preventing java.lang.OutOfMemoryError: unable to create new native thread by Craig Andrews is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
2 thoughts on “Preventing java.lang.OutOfMemoryError: unable to create new native thread”
I tried this and it worked. The only small detail is that the unit of the JVM option is “k” (not “kb”), so you have to use something like -Xss128k.
“I tried this and it worked. The only small detail is that the unit of the JVM option is “k” (not “kb”), so you have to use something like -Xss128k.”
Amazing all kinds of awesome facts!.
Nicely put, Thanks.