java.lang.OutOfMemoryError: unable to create new native thread(转)

解决 - java.lang.OutOfMemoryError: unable to create new native thread

工作中碰到过这个问题好几次了,觉得有必要总结一下,所以有了这篇文章,这篇文章分为三个部分:认识问题、分析问题、解决问题。 

一、认识问题: 

首先我们通过下面这个 测试程序 来认识这个问题:

运行的环境 (有必要说明一下,不同环境会有不同的结果):32位 Windows XP, 1.5.0_22, myeclipse 6.6,

测试程序: 

Java代码 

import java.util.concurrent.CountDownLatch;   

public class TestNativeOutOfMemoryError {   

    public static void main(String[] args) {   

        for (int i = 0;; i++) {   

            System.out.println("i = " + i);   

            new Thread(new HoldThread()).start();   

        }   

    }   

}   

 

class HoldThread extends Thread {   

    CountDownLatch cdl = new CountDownLatch(1);   

 

    public HoldThread() {   

        this.setDaemon(true);   

    }   

    public void run() {   

        try {   

            cdl.await();   

        } catch (InterruptedException e) {   

        }   

    }   

}  

import java.util.concurrent.CountDownLatch;

public class TestNativeOutOfMemoryError {

public static void main(String[] args) {

  for (int i = 0;; i++) {

   System.out.println("i = " + i);

   new Thread(new HoldThread()).start();

  }

}

}

class HoldThread extends Thread {

CountDownLatch cdl = new CountDownLatch(1);

public HoldThread() {

  this.setDaemon(true);

}

public void run() {

  try {

   cdl.await();

  } catch (InterruptedException e) {

  }

}

}  

 

不指定任何JVM参数,eclipse中直接运行输出,看到了这位朋友了吧:

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

    at java.lang.Thread.start0(Native Method)

    at java.lang.Thread.start(Thread.java:597)

    at TestNativeOutOfMemoryError.main(TestNativeOutOfMemoryError.java:20) 

 

二、分析问题: 

这个异常问题本质原因是我们创建了太多的线程,而能创建的线程数是有限制的,导致了异常的发生。能创建的线程数的具体计算公式如下: 

(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads 

MaxProcessMemory 指的是一个进程的最大内存

JVMMemory         JVM内存

ReservedOsMemory  保留的操作系统内存

ThreadStackSize      线程栈的大小

在java语言里, 当你创建一个线程的时候,虚拟机会在JVM内存创建一个Thread对象同时创建一个操作系统线程,而这个系统线程的内存用的不是JVMMemory,而是系统中剩下的内存(MaxProcessMemory - JVMMemory - ReservedOsMemory)。 

 

结合上面例子我们来对公式说明一下: 

MaxProcessMemory 在32位的 windows下是 2G

JVMMemory   eclipse默认启动的程序内存是64M

ReservedOsMemory  一般是150M左右

ThreadStackSize 32位 JDK 1.5默认的stacksize 256K左右

公式如下:

(2*1024*1024-64*1024-150*1024)/256 = 7336 

公式计算所得7336,和实践7117基本一致(有偏差是因为ReservedOsMemory不能很精确) 

由公式得出结论:你给JVM内存越多,那么你能创建的线程越少,越容易发生java.lang.OutOfMemoryError: unable to create new native thread。 

咦,有点背我们的常理,恩,让我们来验证一下,依旧使用上面的测试程序,加上下面的JVM参数,测试结果如下: 

ThreadStackSize      JVMMemory                    能创建的线程数

默认的256K             -Xms64m -Xmx64m    i = 7117

默认的256K             -Xms32m -Xmx32m    i = 7244

-Xss128k             -Xms64m -Xmx64m    i = ? 

完全和公式一致。 

三、解决问题: 

1, 如果程序中有bug,导致创建大量不需要的线程或者线程没有及时回收,那么必须解决这个bug,修改参数是不能解决问题的。

2, 如果程序确实需要大量的线程,现有的设置不能达到要求,那么可以通过修改MaxProcessMemory,JVMMemory,ThreadStackSize这三个因素,来增加能创建的线程数:

a, MaxProcessMemory 使用64位操作系统

b, JVMMemory   减少JVMMemory的分配

c, ThreadStackSize  减小单个线程的栈大小

http://blog.csdn.net/kesay/article/details/5728810

 

时间: 2024-08-03 08:51:28

java.lang.OutOfMemoryError: unable to create new native thread(转)的相关文章

java.lang.OutOfMemoryError: unable to create new native thread如何解决

工作中碰到过这个问题好几次了,觉得有必要总结一下,所以有了这篇文章,这篇文章分为三个部分:认识问题.分析问题.解决问题.   一.认识问题: 首先我们通过下面这个 测试程序 来认识这个问题:运行的环境 (有必要说明一下,不同环境会有不同的结果):32位 Windows XP,Sun JDK 1.6.0_18, eclipse 3.4, 测试程序: Java代码   import java.util.concurrent.CountDownLatch;      public class Test

java.lang.OutOfMemoryError: unable to create new native thread这个异常怎么解决?

问题描述 2011-3-1516:39:49org.apache.catalina.core.StandardWrapperValveinvoke严重:Servlet.service()forservletactionthrewexceptionjava.lang.OutOfMemoryError:unabletocreatenewnativethreadatjava.lang.Thread.start0(NativeMethod)atjava.lang.Thread.start(Unknown

solr-nutch:unable to create new native thread

问题描述 nutch:unable to create new native thread 使用nutch爬取时,报错,以下是日志,哪位大神给我解答下java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:597) at java.util.concurrent.Thr

springmvc 实现文件下载 出现异常java.lang.OutOfMemoryError: Java heap space

问题描述 springmvc 实现文件下载 出现异常java.lang.OutOfMemoryError: Java heap space 网上找解决方案,一般都是tomcat中添加-Xms256m -Xms512m等配置,但是不行啊. 我的是MyEclipse里的tomcat. 下载20M(包括)以内的文件没问题,超过就会报异常,有什么解决办法吗? 还有是不是请求下载文件时,服务器会把文件全部装入内存再发过来,还是分成多个部分发送,超过内存大小的文件如何发送呢? ** --异常信息 ** ty

公司的系統點擊一個功能的時候報java.lang.OutOfMemoryError: PermGen space

问题描述 在公司的系統中點擊了一個打印的功能,前臺是用flex,后臺是java,打印的時候是彈出來一個jsp頁面,中間夾了大量的計算.在本地測試沒事 可以彈出來jsp頁面,但是放在測試機上時候就會報如下異常,我在測試服務器的環境變量里設置了 变名:JAVA_OPTS 变量值:-Xms1024m -Xmx1024m 還是沒有作用,不知道應該怎么處理了.是程序的問題嗎?java.lang.OutOfMemoryError: PermGen spaceat java.lang.ClassLoader.

java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得

我遇到这样的问题,本地部署时抛出异常java.lang.OutOfMemoryError:GC overhead limit exceeded导致服务起不来,查看日志发现加载了太多资源到内存,本地的性能也不好,gc时间消耗的较多.解决这种问题两种方法是,增加参数,- XX:-UseGCOverheadLimit,关闭这个特性,同时增加heap大小,-Xmx1024m.坑填了,but why? OOM大家都知道,就是JVM内存溢出了,那GC overhead limit exceed呢? GC o

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ex.activity/com.ex.activity.LoginActivity}: android.view.InflateException: Bina

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ex.activity/com.ex.activity.LoginActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class   异常解决方案: 是因为设置background的图片太大了,造成了内存溢出,在Activity设置onCrea

服务器java.lang.OutOfMemoryError: allocLargeArray内存溢出的解决

今天一个web服务器不工作了,查看日志.tomcat报出如下信息: Caused by: java.lang.OutOfMemoryError: allocLargeArray - Object size: 80040, Num elements: 40010 以上日志信息基本的意思是程序要分配一个大小为 80040字节的数组(在JVM中数组也是对象,也是在heap中分配的),40010是指数组元素的多少.但是分配这个数组的时候, heap没有可用的空间了. 针对以上情况,解决办法如下: A:调

Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结(转)

java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的原因大都出于以下原因:JVM内存过小.程序不严密,产生了过多的垃圾. 导致OutOfMemoryError异常的常见原因有以下几种: 内存中加载的数据量过于庞大,如一次从数据库取出过多数据: 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收: 代码中存在死循环或循环产生过多重复的对象实体: 使用的第三方软件中的BUG: 启动参数内存值设定的过小: 此错误常见的错误提示: tomcat