zoukankan      html  css  js  c++  java
  • 内存溢出排查

    一、问题:

      春节将至,系统访问量进入高峰期。随之系统出现了异常:java.lang.OutOfMemoryError: unable to create new native thread。在解决这个问题中,尝试了各种方法,最后竟然是因为它......

    二、解决办法:

    1、 关于这个问题,一开始猜想是因消息队列(activemq)引起的,因为处理数据较多,开启的线程数较多导致,因此对MQ搭建了集群。

      MQ集群搭建方法:http://blog.csdn.net/jiangxuchen/article/details/8004561

      但是搭建集群后发现,并不是,问题依旧。

      继续......

    2、 接下来怀疑是系统里开的线程数太多,在优化后,问题仍然存在。

          继续......

    3、 内存调优,减小xss值、JVM内存,仍然解决不了。

          继续......

    4、 几番周测,在整理思路后,决定首要任务就是如何重现该问题,于是编写测试程序,测试出操作系统最大能够创建的线程数:

        

     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     }  

       运行后:

      i = 982
      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)

      问题重现,在反复运行几次后发现,生产系统最大只能创建980多个线程,生产系统操作系统64位centeros,jdk1.7,64G内存。而我本地PC电脑都可以创建2500左右。

      感觉原因快找到了,切换到运行账户使用命令:

      $ su Bst118

      $ ulimit -u

      $ 1024

      生产上所有程序都是在Bst118账户下运行,于是查看该账户下所有的线程数总和为950,也即是说,随时都可能会超过1024,导致内存溢出。查看看进程当前运行的线程数命令为:pstree -p 3660 | wc -l

      原因找到,操作系统对运行程序的账户有最大线程数限制。

      $ vim /etc/security/limits.d/90-nproc.conf
      

      打开后发现除了root,其他账户都限制在1024个。

      于是增加一条:Bst118     soft    nproc     20000

      为什么设置为20000,因为测试后发现,在运行到35000左右,系统就报内存溢出了,操作系统所有命令都不能使用,因此将程序最大线程数限制在20000。

      修改后再没出现内存溢出错误。问题解决。

    三、思考

      1、经过总结,在遇到问题后,不能盲目的到处修改,首先要做的就是重现问题,顺藤摸瓜,逐步的找出根本原因。

  • 相关阅读:
    Java基础之IO流,使用File类以树形结构打印指定文件目录
    Java基础之IO流,以字节流的方式操作读写文件FileOutputStream和FileInputStream的使用
    Java基础之IO流,自定义字节流缓冲区装饰类(模仿)
    Java基础之IO流,转换流应用InputStreamReader,OutputStreamWriter
    碰撞处理游戏的原型
    flash中物体运动基础之六方向与角度
    flash中物体运动基础之七碰撞处理
    推导坐标旋转公式
    flash中物体运动基础之一匀速运动
    flash中物体运动基础之五障碍物
  • 原文地址:https://www.cnblogs.com/myshare/p/5177135.html
Copyright © 2011-2022 走看看