分享

【转】解决 java.lang.OutOfMemoryError: unable to create new native thread

 KILLKISS 2013-01-25

工作中碰着过这个题目好几次了,感觉有须要总结一下,所以有了这篇文章,这篇文章分为三个项目组:熟悉题目、解析题目、解决题目。


 


一、熟悉题目:


起首我们经由过程下面这个 测试法度 来熟悉这个题目:
运行的景象
(有须要申明一下,不合景象会有不合的成果):32位 Windows XP,Sun JDK 1.6.0_18, eclipse 3.4,

测试法度:




Java代码  



  1. import java.util.concurrent.CountDownLatch;  

  2.   

  3. public class TestNativeOutOfMemoryError {  

  4.   

  5.     public static void main(String[] args) {  

  6.   

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

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

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

  10.         }  

  11.     }  

  12.   

  13. }  

  14.   

  15. class HoldThread extends Thread {  

  16.     CountDownLatch cdl = new CountDownLatch(1);  

  17.   

  18.     public HoldThread() {  

  19.         this.setDaemon(true);  

  20.     }  

  21.   

  22.     public void run() {  

  23.         try {  

  24.             cdl.await();  

  25.         } catch (InterruptedException e) {  

  26.         }  

  27.     }  

  28. }  


 


 


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

i = 5602

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  一般是130M阁下

ThreadStackSize 32位 JDK 1.6默认的stacksize 325K阁下

公式如下:

(2*1024*1024-64*1024-130*1024)/325 = 5841

公式策画所得5841,和实践5602根蒂根基一致(有误差是因为ReservedOsMemory不克不及很正确)


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


咦,有点背我们的常理,恩,让我们来验证一下,依旧应用上方的测试法度,加高低面的JVM参数,测试成果如下:
ThreadStackSize      JVMMemory                    能创建的线程数

默认的325K             -Xms1024m -Xmx1024m    i = 2655

默认的325K               -Xms1224m -Xmx1224m    i = 2072

默认的325K             -Xms1324m -Xmx1324m    i = 1753

默认的325K             -Xms1424m -Xmx1424m    i = 1435

-Xss1024k             -Xms1424m -Xmx1424m    i = 452

完全和公式一致。

三、解决题目:
1, 若是法度中有bug,导致创建多量不须要的线程或者线程没有及时收受接管,那么必须解决这个bug,批改参数是不克不及解决题目的。

2, 若是法度确切须要多量的线程,现有的设置不克不及达到请求,那么可以经由过程批改MaxProcessMemory,JVMMemory,ThreadStackSize这三个身分,来增长能创建的线程数:

a, MaxProcessMemory 应用64位操纵体系

b, JVMMemory   削减JVMMemory的分派

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多