java.lang.OutOfMemoryError: unable to create new native thread原因排查

1. 序言

  • 最近,在使用mvn test命令跑单员测试时,遇到了java.lang.OutOfMemoryError: unable to create new native thread错误
  • unable to create new thread类型的OOM错误,一般都发生在应用程序无法创建新线程时候
  • 其出现的原因主要分为两种:
    • 系统内存耗尽,无法为新线程分配内存
    • 创建线程数超过了操作系统的限制(linux中可以通过ulimit -a查看系统的最大线程数)
  • 这篇博客讲了很多排查上述错误的方法和实例: Troubleshoot OutOfMemoryError: Unable to Create New Native Thread
  • 还有一篇中文翻译:解决OutOfMemoryError: unable to create new native thread问题

2. 具体的排查方法

  • solution 1:通过堆栈信息,确定是否存在创建线程过多的问题
    • 创建了多少线程?过度创建的线程的堆栈信息是什么?谁创建了这些线程?
    • 一旦了解清楚,就能很快解决OOM的问题
  • Solution 2:增加操作系统的线程数
    • 通过ulimit -a查看操作系统的最大线程数,这里假设为1024
    • 如果应用程序所需的线程数超过1024,可以通过增大操作系统的线程数解决问题
  • Solution 3:增加机器内存
    • 如果发现操作系统的线程数并未达到上限,说明应用程序需要更多的内存来创建线程
    • 此时,增加机器内存便可以解决问题
  • Solution 4:减少JVM堆内存(-Xmx
    • 增加机器内存涉及硬件操作,不是最佳的选择
    • 这时,不要忘记:线程不是在JVM的堆内存中创建的
    • 如果为JVM分配堆内存后,剩余内存较少,也会导致OOM: unable to create new native thread
    • 在JDK 1.8中,需要减少–Xmx配置的值;在JDK 1.7中,需要减少堆内存和永久代内存( –Xmx-XX:MaxPermSize
  • Solution 5: 减少进程数
    • 减少进程数,与较少堆内存相似
    • 如果Java进程数过多,即使每个进程使用的堆内存不大,但累积起来也会导致剩余内存较少,从而出现OOM: unable to create new native thread
  • Solution 6: 减少线程栈大小(-Xss
    • 如果每个线程的堆栈较大,应用程序整体消耗的内存也会变大
    • 可以根据实际情况,减少线程的堆栈大小,即通过–Xss设置线程堆栈为一个合理的、较小值
    • 注意:-Xss不是设置得越小越好,过小的-Xss值会导致应用程序出现java.lang.StackOverflowError错误,甚至都无法启动JVM

3. 后记

  • 博客Troubleshoot OutOfMemoryError: Unable to Create New Native Thread,还介绍了如何通过http://fastthread.io/进行dump文件分析
  • 有空,可以阅读作者是如何借助http://fastthread.io/分析OOM原因的。甚至,可以亲自体验下http://fastthread.io/

你可能感兴趣的:(#,《深入理解Java,虚拟机》,java相关,java)