“java.lang.OutOfMemoryError: 無法創建新的原生 Thread”

2022-08-31 07:32:21

我们在32k线程(ps -eLF)之后获得8GB RAM VM|grep -c java)"java.lang.OutOfMemoryError : unable to create new native Thread

然而。JDk是64位的,并尝试使用HotSpot和JRockit.Server有Linux 2.6.18"top" and "free -m" shows 50% free memory available

我们还尝试了调整和max process(ulimit -u)限制,limit.conf增加,但都是徒劳的。OS stack size (ulimit -s)

此外,我们尝试了几乎所有可能的堆大小组合,保持低,高等。

我们用来运行应用程序的脚本是

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

感谢您的回复。

我们尝试过编辑 /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

答案 1

这不是内存问题,即使异常名称高度表明这一点,但操作系统资源问题。您的本机线程即将用完,即操作系统将允许您的 JVM 使用多少个线程。

这是一个不常见的问题,因为您很少需要那么多。您是否有很多无条件线程生成线程,线程应该完成但未完成?

如果可能的话,您可以考虑重写为在执行器的控制下使用可调用/可运行。有很多标准执行器具有各种行为,您的代码可以轻松控制这些行为。

(线程数量有限的原因有很多,但它们因操作系统而异)


答案 2

我在负载测试期间遇到了同样的问题,原因是因为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);`

根本原因:JVM 在JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR(资源耗尽(表示内存耗尽))或JVMTI_RESOURCE_EXHAUSTED_THREADS(线程耗尽)时引发此异常。

在我的情况下,Jboss创建了太多的线程,无法为请求提供服务,但是所有线程都被阻止了。正因为如此,JVM的线程和内存都被耗尽了(每个线程都持有内存,这不会释放,因为每个线程都被阻塞)。

分析了Java线程转储,观察到近61K线程被我们的一种方法阻止,这导致了这个问题 。下面是线程转储的部分

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

推荐