162

We are getting "java.lang.OutOfMemoryError : unable to create new native Thread" on 8GB RAM VM after 32k threads (ps -eLF| grep -c java)

However, "top" and "free -m" shows 50% free memory available. JDk is 64 bit and tried with both HotSpot and JRockit.Server has Linux 2.6.18

We also tried OS stack size (ulimit -s) tweaking and max process(ulimit -u) limits, limit.conf increase but all in vain.

Also we tried almost all possible of heap size combinations, keeping it low, high etc.

The script we use to run application is

/opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m -Xss128k -jar JavaNatSimulator.jar /opt/tools/jnatclients/natSimulator.properties

We have tried editing /etc/security/limits.conf and ulimit but still that same

[root@jboss02 ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 72192
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 72192
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
TylerH
  • 20,799
  • 66
  • 75
  • 101
Deepak Tewani
  • 1,687
  • 2
  • 11
  • 7
  • 13
    Operating systems have limits on the number of threads that you can create. Why are you creating more than 32k threads? Your system does most likely not have thousands of processor cores, creating so many threads is not useful. Use a thread pool (`ExecutorService`) instead. – Jesper May 28 '13 at 10:11
  • Thanks for the reply. We are using an open source library and trying to load test that. Any that open source library is creating so many threads. But what i dont understand, is when "top" is showing 50% free memory then why OutOfMemory Error. – Deepak Tewani May 28 '13 at 10:27
  • The open source library that we are using in ICE4j Library – Deepak Tewani May 28 '13 at 10:31
  • 17
    OutOfMemoryError does **not** necessarily mean heap space, or "general" RAM, was exhausted. In this case it's clear that the failure was due to the OS not having the resources to allocate an extra thread. Having 50% free memory is irrelevant to this particular failure. – Andrzej Doyle May 28 '13 at 10:36
  • 2
    What are the other resources required for creating new threads. We were under the impression that if we increase the RAM, then we may able to create more threads. Kindly guide us – Deepak Tewani May 28 '13 at 10:44
  • We tried using ExecutorService, then also number of threads are 32K, it is because all threads are forever live threads. – Deepak Tewani May 28 '13 at 12:30
  • there is seems to be some open source lib which creating threads but not able to finish/stop the threads properly, may be all the threads were created and went into sleep mode. – Omer Jul 05 '18 at 19:14
  • @DeepakTewani - I am facing a similar issue. Did you get the solution? – Harshad Chhaiya Feb 25 '20 at 09:55

15 Answers15

98

This is not a memory problem even though the exception name highly suggests so, but an operating system resource problem. You are running out of native threads, i.e. the amount of threads the operating system will allow your JVM to use.

This is an uncommon problem, because you rarely need that many. Do you have a lot of unconditional thread spawning where the threads should but doesn't finish?

You might consider rewriting into using Callable/Runnables under the control of an Executor if at all possible. There are plenty of standard executors with various behavior which your code can easily control.

(There are many reasons why the number of threads is limited, but they vary from operating system to operating system)

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
  • Thanks for the reply. We are using an open source library ICE4j and trying to load test that. Cant we increase the limit of threads in OS when we know that there is 50% memory left on the server. – Deepak Tewani May 28 '13 at 10:37
  • 1
    Possibly, but I think it will not help you as such. If you run out of resources when load testing you need to be able to control what happens in your application. Why do you have 32000 threads active at once? – Thorbjørn Ravn Andersen May 28 '13 at 10:44
  • We are creating 11K clients that uses 32 K threads for reading, writing data on UDP sockets. Out of these 32 K threads, 10K threads are keep alive threads that are used to keep the socket open – Deepak Tewani May 28 '13 at 10:50
  • I believe this problem is solved in modern web servers. Also udp can loose packets - any reason you do not just use a web server? – Thorbjørn Ravn Andersen May 28 '13 at 11:01
  • We cant use web servers because, what are we creating are clients that would talk with other clients. Both the clients can be behind symmetric, asymmetric nats . For their connectivity , we are using ice4j library. What i am not able to understand is , if server has 50% memory left then what jvm is not able to create more threads – Deepak Tewani May 28 '13 at 11:05
  • 10
    Because OutOfMemory exception should have been named OutOfResources. The operating system cannot provide the resource you need. (And it turned out I did not know ice4j) – Thorbjørn Ravn Andersen May 28 '13 at 11:09
  • So , if we use 16GB RAM (double the memory that we are using now), then,are we able to create double number threads then now? – Deepak Tewani May 28 '13 at 11:22
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/30753/discussion-between-deepak-tewani-and-thorbjorn-ravn-andersen) – Deepak Tewani May 28 '13 at 11:35
  • You misunderstand. The reason Linux does not give you more threads is not because it is running out of memory but because you run into a limit set by Linux itself (this can be an arbitrary rule or because the data structure used isn't any larger). Note that regardless of how much you raise this limit your application must still be able to cope. I suggest you revisit your "a thread per connection" design. – Thorbjørn Ravn Andersen May 28 '13 at 13:29
  • We also tried ExecutorService for thread and then also the application is creating 32K threads. ExecutorService is creating so many threads because all the threads created by application are forever live threads. I understand that, Linux have a limit of giving threads to an application, but cant we increase this limit? – Deepak Tewani May 28 '13 at 14:15
  • Probably, but not something I've interested me for so I do not know how. Consider opening a new question asking that on the Linux SE site. – Thorbjørn Ravn Andersen May 28 '13 at 17:02
  • Also consider finding out how the ice4j community suggest you should solve this problem. You might have missed something in the documentation. – Thorbjørn Ravn Andersen May 28 '13 at 17:04
  • @DeepakTewani - Perhaps running two or more copies of your program will do what you want? Still, I'd think if you are running the system low on threads and things are still working, most likely your program passed the load test. :-) – T.E.D. Aug 28 '13 at 13:43
16

I encountered same issue during the load test, the reason is because of JVM is unable to create a new Java thread further. Below is the JVM source code

if (native_thread->osthread() == NULL) {    
// No one should hold a reference to the 'native_thread'.    
    delete native_thread;   
if (JvmtiExport::should_post_resource_exhausted()) {      
    JvmtiExport::post_resource_exhausted(        
        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 
        JVMTI_RESOURCE_EXHAUSTED_THREADS, 
        "unable to create new native thread");    
    } THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "unable to create new native thread");  
} Thread::start(native_thread);`

Root cause : JVM throws this exception when JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR (resources exhausted (means memory exhausted) ) or JVMTI_RESOURCE_EXHAUSTED_THREADS (Threads exhausted).

In my case Jboss is creating too many threads , to serve the request, but all the threads are blocked . Because of this, JVM is exhausted with threads as well with memory (each thread holds memory , which is not released , because each thread is blocked).

Analyzed the java thread dumps observed nearly 61K threads are blocked by one of our method, which is causing this issue . Below is the portion of Thread dump

"SimpleAsyncTaskExecutor-16562" #38070 prio=5 os_prio=0 tid=0x00007f9985440000 nid=0x2ca6 waiting for monitor entry [0x00007f9d58c2d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
Graham
  • 7,431
  • 18
  • 59
  • 84
Madhu Cheepati
  • 809
  • 5
  • 12
11

If jvm is started via systemd, there might be a maxTasks per process limit (tasks actually mean threads) in some linux OS.

You can check this by running "service status" and check if there is a maxTasks limit. If there is, you can remove it by editing /etc/systemd/system.conf, adding a config: DefaultTasksMax=infinity

Clement.Xu
  • 1,228
  • 2
  • 15
  • 24
  • 2
    To expand on this, if you SSH into a server infected by systemd and then start a java process from CLI, you can also hit the silly tasks limit imposed on the **sshd** service. – sayap Aug 11 '20 at 07:52
  • Thanks! This is one of the solutions for thread problem. There's also an option called TasksMax (for more isolated settings) for services/systemd that are under [Service] TasksMax=(value). At SUSE, the default value is 512 (which is very limited for production use). More info https://www.suse.com/support/kb/doc/?id=000015901 systemctl daemon-reload, and to check, systemctl show --property DefaultTasksMax (for global) or systemctl status ${serviceName}|grep -e Tasks (for TasksMax) There's other things that cause "unable to create new native Thread” issues, such as the ulimit setup. – Ivan Herlambang Aug 29 '20 at 12:39
9

It's likely that your OS does not allow the number of threads you're trying to create, or you're hitting some limit in the JVM. Especially if it's such a round number as 32k, a limit of one kind or another is a very likely culprit.

Are you sure you truly need 32k threads? Most modern languages have some kind of support for pools of reusable threads - I'm sure Java has something in place too (like ExecutorService, as user Jesper mentioned). Perhaps you could request threads from such a pool, instead of manually creating new ones.

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
  • 1
    Thanks for the reply We are using an open source library ICE4j and trying to load test that. Cant we increase the limit of threads in OS when we know that there is 50% memory left on the server. – Deepak Tewani May 28 '13 at 10:35
  • 1
    We are creating 11K clients that uses 32 K threads for reading, writing data on UDP sockets. Out of these 32 K threads, 10K threads are keep alive threads that are used to keep the socket open – Deepak Tewani May 28 '13 at 11:01
7

I would recommend to also look at the Thread Stack Size and see if you get more threads created. The default Thread Stack Size for JRockit 1.5/1.6 is 1 MB for 64-bit VM on Linux OS. 32K threads will require a significant amount of physical and virtual memory to honor this requirement.

Try to reduce the Stack Size to 512 KB as a starting point and see if it helps creating more threads for your application. I also recommend to explore horizontal scaling e.g. splitting your application processing across more physical or virtual machines.

When using a 64-bit VM, the true limit will depend on the OS physical and virtual memory availability and OS tuning parameters such as ulimitc. I also recommend the following article as a reference:

OutOfMemoryError: unable to create new native thread – Problem Demystified

P-H
  • 377
  • 3
  • 5
5

I had the same problem due to ghost processes that didn't show up when using top in bash. This prevented the JVM to spawn more threads.

For me, it resolved when listing all java processes with jps (just execute jps in your shell) and killed them separately using the kill -9 pid bash command for each ghost process.

This might help in some scenarios.

mac7
  • 166
  • 1
  • 6
4

This error can surface because of following two reasons:

  • There is no room in the memory to accommodate new threads.

  • The number of threads exceeds the Operating System limit.

I doubt that number of thread have exceeded the limit for the java process

So possibly chances are the issue is because of memory One point to consider is

threads are not created within the JVM heap. They are created outside the JVM heap. So if there is less room left in the RAM, after the JVM heap allocation, application will run into “java.lang.OutOfMemoryError: unable to create new native thread”.

Possible Solution is to reduce the heap memory or increase the overall ram size

Maverick
  • 626
  • 6
  • 11
4

I had the same problem in a centOS/Red Hat machine. You are reaching the threads limit, for the user, process, or an overall limit

In my case there was a limit on the number of threads a user can have. Which can be checked with, the line saying max user processes

ulimit -a

You can see how many threads are running using this command

$ ps -elfT | wc -l

To get how many threads your process is running (you can get your process pid using top or ps aux):

$ ps -p <PROCESS_PID> -lfT | wc -l

The /proc/sys/kernel/threads-max file provides a system-wide limit for the number of threads. The root user can change that value

To change the limits (in this case to 4096 threads):

$ ulimit -u 4096

You can find more info here for Red Hat/centOs http://www.mastertheboss.com/jboss-server/jboss-monitoring/how-to-solve-javalangoutofmemoryerror-unable-to-create-new-native-thread

Jose1755
  • 378
  • 3
  • 10
2

You have a chance to face the java.lang.OutOfMemoryError: Unable to create new native thread whenever the JVM asks for a new thread from the OS. Whenever the underlying OS cannot allocate a new native thread, this OutOfMemoryError will be thrown. The exact limit for native threads is very platform-dependent thus its recommend to find out those limits by running a test similar to the below link example. But, in general, the situation causing java.lang.OutOfMemoryError: Unable to create new native thread goes through the following phases:

  1. A new Java thread is requested by an application running inside the JVM
  2. JVM native code proxies the request to create a new native thread to the OS The OS tries to create a new native thread which requires memory to be allocated to the thread
  3. The OS will refuse native memory allocation either because the 32-bit Java process size has depleted its memory address space – e.g. (2-4) GB process size limit has been hit – or the virtual memory of the OS has been fully depleted
  4. The java.lang.OutOfMemoryError: Unable to create new native thread error is thrown.

Reference: https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread

Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
2

To find which processes are creating threads try:

ps huH

I normally redirect output to a file and analysis the file offline (is thread count for each process is as expected or not)

1

If your Job is failing because of OutOfMemory on nodes you can tweak the number of max maps and reducers and the JVM opts for each. mapred.child.java.opts (the default is 200Xmx) usually has to be increased based on your data nodes specific hardware.

This link might be helpful.

Marino
  • 800
  • 1
  • 12
  • 26
Pavan Kumar K
  • 1,360
  • 9
  • 11
1

your JBoss configuration has some issues, /opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m Xms and Xmx are limiting your JBoss memory usage, to the configured value, so from the 8Gb you have the server is only ussing 512M + some extra for his own purpose, increase that number, remember to leave some free for the OS and other stuff running there and may be you get it running despite de unsavoury code. Fixing the code would be nice too, if you can.

0

I had this same issue and it turned out to be an improper usage of an java API. I was initializing a builder in a batch processing method that was that not supposed to be initiallized more than once.

Basically I was doing something like:

for (batch in batches) {
    process_batch(batch)
}

def process_batch(batch) {
    var client = TransportClient.builder().build()
    client.processList(batch)
}

when I should have done this:

for (batch in batches) {
    var client = TransportClient.builder().build()
    process_batch(batch, client)
}

def process_batch(batch, client) {
    client.processList(batch)
}
anthonybell
  • 5,790
  • 7
  • 42
  • 60
0

Are you starting your java app with system.d? This is for you!

I recently stumbled over DefaultTasksMax [1] which for some reason was limited to 60 on my machine - not enough for my new keycloak installation.

Keycloak crashes with java.lang.OutOfMemoryError : unable to create new native Thread as soon as it hits the '60' limit (ps -elfT | grep keycloak|wc -l).

Solution

1. Look up your system.d settings

systemctl show --property DefaultTasksMax

In my case. This printed 60

2. Provide a higher value

editor /etc/systemd/system.conf

Edit:

DefaultTasksMax=128

You can also set a similar value TaskMax in your Unit-File. See [2].

3. Reload, Check, Restart

systemctl daemon-reload
systemctl show --property DefaultTasksMax
systemctl start keycloak

[1] https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html

[2] https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html

jschnasse
  • 8,526
  • 6
  • 32
  • 72
-6

First of all I wouldn't blame that much the OS/VM.. rather the developer who wrote the code that creates sooo many Threads. Basically somewhere in your code (or 3rd party) a lot of threads are created without control.

Carefully review the stacktraces/code and control the number of threads that get created. Normally your app shouldn't need a large amount of threads, if it does it's a different problem.

Flueras Bogdan
  • 9,187
  • 8
  • 32
  • 30