Dee*_*ani 113 java out-of-memory
"java.lang.OutOfMemoryError : unable to create new native Thread在32k线程之后我们得到"8GB RAM VM(ps -eLF | grep -c java)
但是,"top" and "free -m" shows 50% free memory available.JDk是64位,并尝试使用HotSpot和JRockit.Server有Linux 2.6.18
我们还试过OS stack size (ulimit -s)调整和最大进程(ulimit -u)限制,limit.conf增加但都是徒劳的.
我们还尝试了几乎所有可能的堆大小组合,保持低,高等.
我们用来运行应用程序的脚本是
/opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m -Xss128k -jar JavaNatSimulator.jar /opt/tools/jnatclients/natSimulator.properties
Run Code Online (Sandbox Code Playgroud)
谢谢回复.
我们已经尝试过编辑/etc/security/limits.conf和ulimit,但仍然是这样
[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
Run Code Online (Sandbox Code Playgroud)
Tho*_*sen 76
这不是内存问题,即使异常名称强烈建议,但操作系统资源问题.您的本机线程已用完,即操作系统允许JVM使用多少个线程.
这是一个不常见的问题,因为你很少需要这么多.你有很多无条件的线程产生线程应该但不完成?
如果可能的话,您可以考虑在Executor的控制下重写使用Callable/Runnables.有许多标准执行程序具有各种行为,您的代码可以轻松控制.
(线程数量有限的原因有很多,但从操作系统到操作系统各不相同)
小智 11
我在加载测试期间遇到了同样的问题,原因是JVM无法进一步创建新的Java线程.下面是JVM源代码
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);`
Run Code Online (Sandbox Code Playgroud)
根本原因:当JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR(资源耗尽(意味着内存耗尽))或JVMTI_RESOURCE_EXHAUSTED_THREADS(线程耗尽)时,JVM会抛出此异常.
在我看来,Jboss正在创建太多线程来提供请求,但是所有线程都被阻止了.因此,JVM耗尽了线程以及内存(每个线程都保留内存,因为每个线程都被阻塞,所以没有释放内存).
分析了java线程转储,观察到近61K线程被我们的一个方法阻塞,这就是造成这个问题的原因.下面是Thread转储的一部分
"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)
Run Code Online (Sandbox Code Playgroud)
Cle*_*.Xu 10
如果 jvm 是通过 systemd 启动的,那么在某些 linux 操作系统中,每个进程可能会有一个 maxTasks 限制(任务实际上是指线程)。
您可以通过运行“服务状态”来检查这一点,并检查是否有 maxTasks 限制。如果有,您可以通过编辑 /etc/systemd/system.conf 删除它,添加一个配置: DefaultTasksMax=infinity
您的操作系统可能不允许您尝试创建的线程数,或者您在JVM中遇到了一些限制.特别是如果它是32k这样的整数,那么这种或那种极限很可能是罪魁祸首.
你确定你真的需要32k线程吗?大多数现代语言都对可重用线程池提供某种支持 - 我确信Java也有适当的东西(就像ExecutorService用户Jesper所提到的那样).也许您可以从这样的池中请求线程,而不是手动创建新线程.
我建议还要查看Thread Stack Size并查看是否创建了更多线程.对于Linux OS上的64位VM ,JRockit 1.5/1.6的默认线程堆栈大小为1 MB.32K线程将需要大量的物理和虚拟内存来满足此要求.
尝试将堆栈大小减小到512 KB作为起点,看看它是否有助于为您的应用程序创建更多线程.我还建议探索横向扩展,例如在更多物理或虚拟机上拆分应用程序处理.
使用64位VM时,真正的限制将取决于OS物理和虚拟内存可用性以及OS调整参数(如ulimitc).我还推荐以下文章作为参考:
OutOfMemoryError:无法创建新的本机线程 - 问题揭秘
我在 centOS/Red Hat 机器上遇到了同样的问题。您即将达到用户、进程或总体限制的线程限制
就我而言,用户可以拥有的线程数量是有限制的。可以通过“最大用户进程数”行进行检查
ulimit -a
您可以使用此命令查看有多少线程正在运行
$ ps -elfT | wc -l
要获取进程正在运行的线程数(可以使用 top 或 ps aux 获取进程 pid):
$ ps -p <PROCESS_PID> -lfT | wc -l
/proc/sys/kernel/threads-max 文件提供系统范围内的线程数限制。root 用户可以更改该值
要更改限制(在本例中为 4096 个线程):
$ ulimit -u 4096
您可以在此处找到有关 Red Hat/centOs 的更多信息http://www.mastertheboss.com/jboss-server/jboss-monitoring/how-to-solve-javalangoutofmemoryerror-unable-to-create-new-native-thread
| 归档时间: |
|
| 查看次数: |
176956 次 |
| 最近记录: |