前言

最近公司的服务器出现了oom的报错,经过一番排查,终于找到了原因。写下这篇博客是为了记录下查找的过程,也是为了帮助那些跟我门遇到的情况相同的人可以更快的寻找到答案。

环境

系统:linux(centos 7)

平台:java

介绍

程序结构介绍

上图为报错程序的结构图,从图中可以看出有一个主的JVM运行主要的java程序,当有请求到达时,对于每个请求都会启动一个JVM去处理请求。

报错介绍

当上面所述的程序接受到的请求超过一定数量时,就会报错 java.lang.OutOfMemoryError: unable to create new native thread

分析步骤

1.通过上面的报错信息可以得到以下结论:(ps:关于内存溢出这块的知识可以查看https://www.cnblogs.com/lin-xuan/p/5271354.html)

  • 该报错是内存溢出导致的
  • 内存溢出的地方在java虚拟机栈或者本地方法栈

2.通过进一步的百度我们找到了以下的解答:

  • 系统内存耗尽,无法为新线程分配内存
  • 创建线程数超过了操作系统的限制

3.通过 top 命令查看在程序运行时内存的使用情况,发现当报错时内存的使用为50%,因此排除了内存耗尽的情况

4.通过 ulimit -u 命令查看系统允许用户最大创建线程数,发现用户最大可以创建1024个线程

5.通过 ulimit -u  命令修改用户最大线程数,再次使用 ulimit -u 查看是否修改成功

6.当我们把用户最大线程数修改为4096时,我们发现可创建的JVM并没有增加多少,因此我们决定模拟环境,来排查具体的原因

7.创建文件SubJVM.java,并且输入以下内容:

  1. import java.util.concurrent.TimeUnit;
  2. public class SubJVM {
  3. public static void main(String...args) throws InterruptedException{
  4. TimeUnit.SECONDS.sleep(30);
  5. }
  6. }

8.创建文件MainJVM.java,并且输入以下内容:

  1. public class MainJVM {
  2. public static void main(String...args) {
  3. for(int i = 0; i < 10000; i++) {
  4. System.out.println("Thread num:" + i);
  5. Thread thread = new Thread(new Runnable() {
  6. @Override
  7. public void run() {
  8. try {
  9. Process ps = Runtime.getRuntime().exec("java SubJVM");
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. });
  15. thread.start();
  16. }
  17. }
  18. }

9.分别将 ulimit -u 设置为1024、4096、10000,然后会的到以下结果:

ulimit -u JVM数
1024 82
4096 298
10000 712

10.这时我们猜想每个JVM中会有若干个线程,统计如下:

  1. 1024/82=12
  2. 4096/298=13
  3. 10000/712=14

11.为了解释我们心中的猜想,我们使用了以下命令查看每个JVM的线程数(请自行百度查看该命令的使用方式):

  1. jstack pid

12.该命令的输出内容如下:

  1. 2018-04-08 01:26:43
  2. Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.80-b11 mixed mode):
  3.  
  4. "Attach Listener" daemon prio=10 tid=0x00007f90c0001000 nid=0x2f3c waiting on condition [0x0000000000000000]
  5. java.lang.Thread.State: RUNNABLE
  6.  
  7. "Service Thread" daemon prio=10 tid=0x00007f90f4097800 nid=0x2d85 runnable [0x0000000000000000]
  8. java.lang.Thread.State: RUNNABLE
  9.  
  10. "C2 CompilerThread1" daemon prio=10 tid=0x00007f90f4095800 nid=0x2d82 waiting on condition [0x0000000000000000]
  11. java.lang.Thread.State: RUNNABLE
  12.  
  13. "C2 CompilerThread0" daemon prio=10 tid=0x00007f90f4092800 nid=0x2d80 waiting on condition [0x0000000000000000]
  14. java.lang.Thread.State: RUNNABLE
  15.  
  16. "Signal Dispatcher" daemon prio=10 tid=0x00007f90f4090000 nid=0x2d6b runnable [0x0000000000000000]
  17. java.lang.Thread.State: RUNNABLE
  18.  
  19. "Finalizer" daemon prio=10 tid=0x00007f90f406f000 nid=0x2d3b in Object.wait() [0x00007f90ed04e000]
  20. java.lang.Thread.State: WAITING (on object monitor)
  21. at java.lang.Object.wait(Native Method)
  22. - waiting on <0x00000000d7404858> (a java.lang.ref.ReferenceQueue$Lock)
  23. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
  24. - locked <0x00000000d7404858> (a java.lang.ref.ReferenceQueue$Lock)
  25. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
  26. at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
  27.  
  28. "Reference Handler" daemon prio=10 tid=0x00007f90f406d000 nid=0x2d37 in Object.wait() [0x00007f90f81b2000]
  29. java.lang.Thread.State: WAITING (on object monitor)
  30. at java.lang.Object.wait(Native Method)
  31. - waiting on <0x00000000d7404470> (a java.lang.ref.Reference$Lock)
  32. at java.lang.Object.wait(Object.java:503)
  33. at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
  34. - locked <0x00000000d7404470> (a java.lang.ref.Reference$Lock)
  35.  
  36. "main" prio=10 tid=0x00007f90f4009000 nid=0x2cf0 waiting on condition [0x00007f90fd824000]
  37. java.lang.Thread.State: TIMED_WAITING (sleeping)
  38. at java.lang.Thread.sleep(Native Method)
  39. at Sleep.main(Sleep.java:4)
  40.  
  41. "VM Thread" prio=10 tid=0x00007f90f4068800 nid=0x2d28 runnable
  42.  
  43. "GC task thread#0 (ParallelGC)" prio=10 tid=0x00007f90f401e800 nid=0x2cf1 runnable
  44.  
  45. "GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f90f4020800 nid=0x2d08 runnable
  46.  
  47. "GC task thread#2 (ParallelGC)" prio=10 tid=0x00007f90f4022800 nid=0x2d13 runnable
  48.  
  49. "GC task thread#3 (ParallelGC)" prio=10 tid=0x00007f90f4024800 nid=0x2d17 runnable
  50.  
  51. "VM Periodic Task Thread" prio=10 tid=0x00007f90f40a2800 nid=0x2d9d waiting on condition
  52.  
  53. JNI global references: 107

13.统计以上信息可知,一个JVM中大概有14个线程,这也解释了为什么增加了 ulimit -u 的值,JVM的数量还是没有达到预期的值。

解决

1.切换到root用户

2.输入以下命令

  1. vim /etc/security/limits.d/20-nproc.conf

3.在文件中加入以下内容:

  1. * soft nproc 4096
  2. root soft nproc unlimited

[java] [error] java.lang.OutOfMemoryError: unable to create new native thread的更多相关文章

  1. 关于“java.lang.OutOfMemoryError : unable to create new native Thread”的报错问题

    好吧 我发誓这是postgresql的Mirroring Controller的RT测试的最后一个坑了. 在这个RT测试的最后,要求测试Mirroring Controller功能在长时间运行下的稳定 ...

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

    工作中碰到过这个问题好几次了,觉得有必要总结一下,所以有了这篇文章,这篇文章分为三个部分:认识问题.分析问题.解决问题. 一.认识问题: 首先我们通过下面这个 测试程序 来认识这个问题:运行的环境 ( ...

  3. JVM内存越多,能创建的线程越少,越容易发生java.lang.OutOfMemoryError: unable to create new native thread。

    一.认识问题: 首先我们通过下面这个 测试程序 来认识这个问题:运行的环境 (有必要说明一下,不同环境会有不同的结果):32位 Windows XP,Sun JDK 1.6.0_18, eclipse ...

  4. spark java.lang.OutOfMemoryError: unable to create new native thread

    最近迁移集群,在hadoop-2.8.4 的yarn上跑 spark 程序 报了以下错误 java.lang.OutOfMemoryError: unable to create new native ...

  5. 剥下“java.lang.OutOfMemoryError: unable to create new native thread”的外衣 创建线程数公式(MaxProcessMemory - JVMMemory – ReservedOsMemory)

    剥下“java.lang.OutOfMemoryError: unable to create new native thread”的外衣 星期一早上到了公司,据称产品环境抛出了最可爱的异常—OutO ...

  6. 解决java.lang.OutOfMemoryError: unable to create new native thread问题

    解决:1.升级JVM到最新的版本 最新版本的JVM一般在内存优化方面做的更好,升级JVM到最新的版本可能会缓解测问题2.从操作系统层面去解决 使用64位操作系统 如果使用32位操作系统遇到unable ...

  7. 记一次内存溢出java.lang.OutOfMemoryError: unable to create new native thread

    一.问题: 春节将至,系统访问量进入高峰期.随之系统出现了异常:java.lang.OutOfMemoryError: unable to create new native thread.在解决这个 ...

  8. JVM虚拟机宕机_java.lang.OutOfMemoryError: unable to create new native thread

    原因:当前用户的系统最最大程序数数已达到最大值,使用ulimit -u可以看到是1024   解决办法:在当前用户下使用ulimit -u 65535 然后再执行jsp,一切ok     功能说明:控 ...

  9. 线程ava.lang.OutOfMemoryError: unable to create new native thread

    近日开发遇到多线程的问题: java.lang.OutOfMemoryError: unable to create new native thread Exception in thread &qu ...

随机推荐

  1. clientdataset 做为 单机数据库的 使用 学习

    http://blog.csdn.net/waveyang/article/details/34146737 unit Unit3; interface uses Winapi.Windows, Wi ...

  2. 【ABAP系列】SAP 关于出口(user-exit)MV50AFZ1的一些问题

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP 关于出口(user-ex ...

  3. 疯狂Java学习

    面向对象(下) 6.3:类成员:又讲了一遍static修饰的类成员:   Singleten(单例)类: 通过封装的方式,实现了一个类只能创建一次,应该是为了更好编写代码,创造的一个概念. 6.4:f ...

  4. 分布式 vs 集群 主从 vs 集群

      理解 分布式 一个业务拆分成多个子业务,部署在不同的服务器上 集群 同一个业务部署在多个服务器上   更新 主从 服务器之间更新是异步的,从服务器可能和主服务器不一致 集群 更新是同步的,数据节点 ...

  5. Sql Server 之游标

    一般来说,我们通过SQL一般是面向集合进行数据操作,但是游标提供给我们更加强大的功能可以对数据集合进行逐行遍历有选择性的操作处理.当然游标也有其不可避免的缺陷就是:低效和复杂.所以一般正常的操作处理不 ...

  6. poj_3179 Corral the Cows (二分+二维前缀和+离散化)

    [题目链接] http://poj.org/problem?id=3179 [参考] http://www.cnblogs.com/evenbao/p/9243183.html [算法] 二分答案+判 ...

  7. 最长回文子序列/最长回文子串(DP,马拉车)

    字符子串和字符子序列的区别 字符字串指的是字符串中连续的n个字符:如palindrome中,pa,alind,drome等都属于它的字串 而字符子序列指的是字符串中不一定连续但先后顺序一致的n个字符: ...

  8. Elasticsearch7.X 入门学习第七课笔记-----Mapping多字段与自定义Analyzer

    原文:Elasticsearch7.X 入门学习第七课笔记-----Mapping多字段与自定义Analyzer 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处 ...

  9. 21、前端知识点--html5和css3新特性汇总

    跳转到该链接 新特性汇总版: https://www.cnblogs.com/donve/p/10697745.html HTML5和CSS3的新特性(浓缩好记版) https://blog.csdn ...

  10. python基础篇(完整版)

    目录 计算机基础之编程和计算机组成 什么是编程语言 什么是编程 为什么要编程 编程语言的分类 机器语言(低级语言) 汇编语言 高级语言 计算机的五大组成 CPU(相当于人类的大脑) 多核CPU(多个大 ...