Analyzing OutOfMemoryError: unable to create new native thread

In your java application if you had seen below error in logs

SOURCE:java.lang.OutOfMemoryError: unable to create new native thread

This means that when java process wants to create a new thread and requested for new process to kernel, but kernel was not able to allocate new process because of the number of processes created by that user reached current limits on max user processes.

You can find the current limits of the user, by running below command

$ ulimit -a

If you check above max user processes which is set to 1024, meaning current user can create 1024 processes, if current processes count exceeds this limit and if any application asking for new process kernel will not allocate new process.

Note there is also a max limit at system level, this we can find from

$ sudo sysctl -a | grep kernel.pid_max
kernel.pid_max = 32768

This means system wide for all users kernel can create 32768 processes.

It is up to the process on how to react when this happened. In case of java we will see SOURCE:java.lang.OutOfMemoryError: unable to create new native thread

You can also find the average load of number of processes created.

$ more /proc/loadavg
7.35 7.83 7.56 6/7802 5393

in above you can see that on an average 7802 processes are getting created.

How to know the current number of processes running for the current user?

$ ps -ef | grep ^app | awk '{print $2}' | grep -v PID | xargs -i sh -c 'ps -p {} -lfT | grep -v PID | wc -l' | awk '{sum+=$1} END {print sum}'

above command searches for all process created by app user and for each process it finds the count of all sub process/threads and sums up all the counts. In above case 7335 processes are currently running for that user app .

You can use a sample program like below to create threads and verify at what point java process will get OutOfMemoryError

Note: Above creates 775 threads, you can increase this number

To fix this, if your system has enough memory, then you can increase the user processes limit. ulimit -u 16384

To make it permanent, you include in ~/.bash_profile

$ more ~/.bash_profile
ulimit -u 16384

or in in /etc/security/limits.conf add below lines

app           soft    nproc          16384
app hard nproc 16384

In order to reflect above changes, the java process should be restarted.

How do we know if above limits got applied?

You can find the limits of all the java processes running in that system by below command.

$ ps -ef | grep "java" | grep -v grep | awk '{print $2}' | grep -v PID | xargs -i sh -c 'echo {}; cat /proc/{}/limits | grep "Max processes"'

in above 60232 only got the new limits, remaining 2 java process needs to be restarted.

Hope this helps.

Software Engineer, Learner, Developer, Prokopton

Software Engineer, Learner, Developer, Prokopton