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

13,496

Solution 1

Why do you create a Thread in the first place?

Your code should implement the Runnable interface instead.

Then, when you decide that you want to run it in a thread, simple instantiate a Thread with the Runnable as the argument and call start() on the Thread object.

If, instead, you just want to run it in your current thread, simply call run() on your Runnable object.

This has several advantages:

  • you don't involve any Thread objects as long as you don't care about separate threads
  • your code is wrapped in a Runnable which fits closer conceptually: you're not writing some special kind of Thread, do you? You simply write some code that can be executed/run.
  • you can easily switch to using an Executor which further abstract away the decision

And last but not least you avoid any potential confusion on whether or not a native thread resource is created.

Solution 2

When you call run() method no new thread should be created. And your objects will be collected by Garbage collector when they are not referenced.

Your other part of code may be creating lot of Threads.

Try using ThreadPoolExecutor (thread pooling) in your code to limit threads in your application, And tune your threadpool size accordingly for better performance.

You can also check following to debug your issue: (referenced from link) There are a few things to do if you encounter this exception.

  • Use the lsof -p PID command (Unix platforms) to see how many threads are active for this process.
  • Determine if there is a maximum number of threads per process defined by the operating system. If the limit is too low for the application, try raising the per-process thread limit.
  • Examine the application code to determine if there is code that is creating threads or connections (such as LDAP connections) and not destroying them. You could dump the Java threads to see if there are an excessive number has been created.
  • If you find that too many connections are opened by the application, make sure that any thread that the application creates is destroyed. An enterprise application (.ear) or Web application (.war) runs under a long-running JVM. Just because the application is finished does not mean that the JVM process ends. It is imperative that an application free any resources that it allocates. Another solution would be for the application to use a thread pool to manage the threads needed.

Solution 3

This link describes quite nicely how this error is thrown by the JVM: http://javaeesupportpatterns.blogspot.ro/2012/09/outofmemoryerror-unable-to-create-new.html

Basically it's very dependent on the OS. On RedHat Linux 6.5 (most likely other distros/version and kernel versions) the max_threads=max_process x 2.

The max number of threads is very dependent on the number of allowed processes. Which the max number of processes is dependent on the max physical memory you have installed.

If you have a look in the limits.conf file (on my RHL 6.5 it's in /etc/security/limits.d/90-nproc.conf). Exert form the file:

# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.

*          soft    nproc     **1024**
root       soft    nproc     unlimited

You'll see that for non root users it's 1024 (which means 2048 max threads).

To see the max number of threads that your user is allowed to create run this command "cat /proc/sys/kernel/threads-max" or "sysctl kernel.threads-max".

To solve an issue like this (at least it worked for me) as root you'll need to ncrease the max allowed threads:

echo 10000 > /proc/sys/kernel/threads-max

This affects all users and the root. The user needs to log out and then log in again for the settings to take affect.

Share:
13,496

Related videos on Youtube

cometta
Author by

cometta

Updated on June 04, 2022

Comments

  • cometta
    cometta almost 2 years

    i saw comment like this

    one place i have seen this problem is if you keep creating threads, and instead of calling start(), call run() directly on the thread object. This will result in the thread object not getting dereferenced... So after sometime the message unable to create new native thread comes up

    on the Sun Java Forums

    In my application, initialy we plan to use thread, but later, we decided no need anymore, so we just call run() instead of start(). Do we need to do manual GC for new threadClass(..) ?

    my tomcat startup setting

    -Xms1024m -Xmx1024m -XX:MaxPermSize=450m 
    
    • sourcerebels
      sourcerebels over 13 years
      But, if you excute run() instead of start() the JVM will not create a new thread. Isn't it?
  • cometta
    cometta over 13 years
    you mean my threadClass extends Thread cause this problem? even though i just call run(),instead of start?
  • Stephen C
    Stephen C over 13 years
    @cornetta - he's not saying that it causes problems. He's saying that it is poor practice to extend Thread.
  • Tassos Bassoukos
    Tassos Bassoukos over 13 years
    Also, in the same vein, why not use an Executor?
  • Joachim Sauer
    Joachim Sauer over 13 years
    @cornetta: as Stephen said, I'm mostly arguing that it's poor practice. However I don't see anything in the documentation of Thread that specifies explicitly whether native resources are allocated during construction of the Thread object or only when the start() method is called. And to avoid any confusion, it's probably better to not involve the Thread class unless you definitely want a separate thread.
  • Joachim Sauer
    Joachim Sauer over 13 years
    @Tassos: Using an Executor is a further step and definitely encouraged (I also mentioned it in my answer).
  • Tassos Bassoukos
    Tassos Bassoukos over 13 years
    @Joachim: Oh dear, indeed - missed that completely. Should stop browsing SO when not fully awake...

Related