java.lang.OutOfMemoryError:无法创建新的本机线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3500773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:07:33  来源:igfitidea点击:

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

javamemory-leaks

提问by cometta

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

我看到这个问题的一个地方是,如果您继续创建线程,而不是调用 start(),而是直接在线程对象上调用 run()。这将导致线程对象不会被取消引用......所以一段时间后,消息无法创建新的本机线程出现

on the Sun Java Forums

Sun Java 论坛上

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(..) ?

在我的应用程序中,最初我们计划使用线程,但后来我们决定不再需要了,所以我们只调用 run() 而不是 start()。我们需要为 new threadClass(..) 做手动 GC 吗?

my tomcat startup setting

我的tomcat启动设置

-Xms1024m -Xmx1024m -XX:MaxPermSize=450m 

回答by Joachim Sauer

Why do you create a Threadin the first place?

你为什么首先创建一个Thread

Your code should implement the Runnableinterface instead.

您的代码应该实现该Runnable接口。

Then, when you decide that you want to run it in a thread, simple instantiate a Threadwith the Runnableas the argument and call start()on the Threadobject.

然后,当你决定要在一个线程中运行它,简单的实例化一个ThreadRunnable作为参数和呼叫start()的上Thread对象。

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

相反,如果您只想在当前线程中运行它,只需调用run()您的Runnable对象即可。

This has several advantages:

这有几个优点:

  • you don't involve any Threadobjects as long as you don't care about separate threads
  • your code is wrapped in a Runnablewhich 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 Executorwhich further abstract away the decision
  • Thread只要您不关心单独的线程,您就不会涉及任何对象
  • 你的代码被包裹在一个Runnable概念上更接近的地方:你不是在写某种特殊的线程,是吗?您只需编写一些可以执行/运行的代码。
  • 您可以轻松切换到使用Executor进一步抽象化决策

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

最后但并非最不重要的一点是,您可以避免任何关于是否创建本机线程资源的潜在混淆。

回答by YoK

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.

当您调用 run() 方法时,不应创建新线程。当你的对象没有被引用时,它们会被垃圾收集器收集。

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.

尝试在代码中使用ThreadPoolExecutor(线程池)来限制应用程序中的线程,并相应地调整线程池大小以获得更好的性能。

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.
  • 使用 lsof -p PID 命令(Unix 平台)查看此进程有多少线程处于活动状态。
  • 确定操作系统是否定义了每个进程的最大线程数。如果应用程序的限制太低,请尝试提高每个进程的线程限制。
  • 检查应用程序代码以确定是否存在创建线程或连接(例如 LDAP 连接)而不是销毁它们的代码。您可以转储 Java 线程以查看是否创建了过多的线程。
  • 如果您发现应用程序打开了太多连接,请确保应用程序创建的任何线程都已销毁。企业应用程序 (.ear) 或 Web 应用程序 (.war) 在长时间运行的 JVM 下运行。仅仅因为应用程序完成并不意味着 JVM 进程结束。应用程序必须释放它分配的任何资源。另一种解决方案是应用程序使用线程池来管理所需的线程。

回答by bobbyus

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

此链接很好地描述了 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.

基本上它非常依赖于操作系统。在 RedHat Linux 6.5(很可能是其他发行版/版本和内核版本)上,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:

如果您查看limits.conf 文件(在我的RHL 6.5 中,它在/etc/security/limits.d/90-nproc.conf 中)。执行表单文件:

# 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).

您会看到,对于非 root 用户,它是 1024(这意味着最大线程数为 2048)。

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".

要查看允许您的用户创建的最大线程数,请运行此命令“cat /proc/sys/kernel/threads-max”或“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:

要以 root 身份解决这样的问题(至少对我有用),您需要增加最大允许线程数:

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

回声 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.

这会影响所有用户和 root。用户需要注销然后重新登录才能使设置生效。