性能文章>OOM系列之五:java.lang.OutOfMemoryError: 无法创建新的本地线程问题详解>

OOM系列之五:java.lang.OutOfMemoryError: 无法创建新的本地线程问题详解转载

4月前
4000020

此文来自于plumbr官网,plumbr作为一个常用的JVM 监测工具,官网有完整的oom和gc文章,准备慢慢全部翻译过来:

第一篇:java.lang.OutOfMemoryError:Java heap space

第二篇:Java.lang.OutOfMemoryError: GC overhead limit exceeded

第三篇:java.lang.OutOfMemoryError: 永久空间

第四篇:java.lang.OutOfMemoryError: 元空间

第五篇:java.lang.OutOfMemoryError: 无法创建新的本地线程

正文:

Java 应用程序本质上是多线程的。这意味着用 Java 编写的程序可以同时(表面上)做几件事。例如——即使在只有一个处理器的机器上——当您将内容从一个窗口拖到另一个窗口时,在后台播放的电影不会因为您一次执行多项操作而停止。

考虑线程的一种方法是将它们视为可以向其提交任务以执行的工人。如果您只有一名工人,他或她当时只能执行一项任务。但是,当您拥有十几个工人时,他们可以同时执行您的多个命令。

现在,与物理世界中的工人一样,JVM 中的线程需要一些肘部空间来执行他们被召唤来处理的工作。当线程多于内存空间时,我们已经为问题奠定了基础:

java-lang-outofmemoryerror-unable-to-create-new-native-thread

消息java.lang.OutOfMemoryError: Unable to create new native thread意味着Java 应用程序已达到它可以启动的线程数限制。

1,什么原因造成的?

您有机会遇到java.lang.OutOfMemoryError: Unable to create new native thread每当 JVM 向操作系统请求新线程时。每当底层操作系统无法分配新的本机线程时,就会抛出此 OutOfMemoryError。本机线程的确切限制非常依赖于平台,因此我们建议通过运行类似于以下示例的测试来找出这些限制。但是,一般情况下,导致java.lang.OutOfMemoryError: Unable to create new native thread 的情况会经历以下几个阶段:

  1. 运行在 JVM 中的应用程序请求一个新的 Java 线程
  2. JVM 本机代码将创建新本机线程的请求代理到操作系统
  3. 操作系统尝试创建一个新的本地线程,该线程需要为线程分配内存
  4. 操作系统将拒绝本机内存分配,因为 32 位 Java 进程大小已耗尽其内存地址空间 - 例如 (2-4) GB 进程大小限制已达到 - 或操作系统的虚拟内存已完全耗尽
  5. java.lang.OutOfMemoryError:无法创建新的本地线程引发错误。

2,举个例子

以下示例在循环中创建并启动新线程。运行代码时,会快速达到操作系统限制并显示java.lang.OutOfMemoryError: Unable to create new native thread消息。

while(true){
    new Thread(new Runnable(){
        public void run() {
            try {
                Thread.sleep(10000000);
            } catch(InterruptedException e) { }        
        }    
    }).start();
}

确切的本机线程限制取决于平台,例如在 Windows、Linux 和 Mac OS X 上的测试表明:

  • 64 位 Mac OS X 10.9,Java 1.7.0_45 – JVM 在 #2031 线程创建后终止
  • 64 位 Ubuntu Linux,Java 1.7.0_45 – JVM 在 #31893 线程创建后终止
  • 64 位 Windows 7、Java 1.7.0_45 – 由于操作系统使用的线程模型不同,此错误似乎不会在此特定平台上引发。在线程 #250,000 上,即使交换文件已增长到 10GB 并且应用程序面临极端的性能问题,该进程仍处于活动状态。

因此,请确保通过调用一个小测试了解自己的限制,并找出何时会触发java.lang.OutOfMemoryError: Unable to create new native thread

3,解决方案

有时,您可以通过增加操作系统级别的限制来绕过无法创建新的本机线程问题。例如,如果您限制了 JVM 可以在用户空间中产生的进程数,您应该检查并可能增加限制:

[root@dev ~]# ulimit -a
核心文件大小(块,-c)0
--- 为简洁起见 ---
最大用户进程 (-u) 1800

通常情况下,OutOfMemoryError 对新本地线程的限制表明存在编程错误。当您的应用程序产生数千个线程时,很可能出现了严重错误——没有多少应用程序可以从如此大量的线程中受益。

解决问题的一种方法是开始进行线程转储以了解情况。你通常会花几天的时间来做这件事。我们的建议是将Plumbr连接到您的应用程序,以找出导致问题的原因以及如何在几分钟内解决它。

请先登录,再评论

暂无回复,快来写下第一个回复吧~

为你推荐

OutOfMemoryError之unable to create new native thread原因分析及6种解决方案
java.lang.OutOfMemoryError:unable to create new native thread 是比较常见的一种异常,表示应用程序无法创建新的线程。产生该异常,总体上可总结
java内存溢出问题分析过程
背景运维人员反馈一个容器化的java程序每跑一段时间就会出现OOM问题,重启后,间隔大概两天后复现。 问题调查 一、查日志由于是容器化部署的程序,登上主机后使用docker logs Containe
为什么容器内存占用居高不下,频频 OOM(续)
在之前的文章《[为什么容器内存占用居高不下,频频 OOM](https://heapdump.cn/article/1589003)》 中,我根据现状进行了分析和说明,收到了很多读者的建议和疑
Java OOM 实战篇:应用故障之Java heap space 堆溢出实战
以下是用于测试OOM的测试代码:```javapublic class HeapMemUseTest { public static void main(String[] args) {
一则OOM死机故障的处理过程
OOM是Out of Memory的简写,也就是内存不足。出现该问题的原因有很多,如程序内存泄漏等。内存泄漏问题可以通过定时地终止和重启有问题的程序来发现和解决。在比较新的Linux内核版本中,有一种
导致程序出现OOM的因素,夜深人静的时候,程序OOM异常追踪
作为Java程序员, 除了享受垃圾回收机制带来的便利外, 还深受OOM(Out Of Memory)的困惑和折磨。 堆溢出(heap)编写如下例程:```javapublic static void
导致程序出现OOM的因素,夜深人静的时候,程序OOM异常追踪
作为Java程序员, 除了享受垃圾回收机制带来的便利外, 还深受OOM(Out Of Memory)的困惑和折磨.先来看下java的内存分布 堆溢出(heap)编写如下例程:```javapublic
首次排查 OOM 实录
前言距离上篇文章更新已经一月有余,之所以一直没更新一是工作最近比较忙,二是感觉产出不了什么对自己和他人有价值的文章。因此这段时间,主要的空闲时间在学习技术和写 GitHub,博客这边就暂时落下了。本篇