zoukankan      html  css  js  c++  java
  • 引用-定位大量占用CPU的问题

    引用-https://www.cnblogs.com/duanxz/p/4159963.html

    问题分析:
    1,程序属于CPU密集型,和开发沟通过,排除此类情况。
    2,程序代码有问题,出现死循环,可能性极大。

    问题解决:
    1,开发那边无法排查代码某个模块有问题,从日志上也无法分析得出。
    2,记得原来通过strace跟踪的方法解决了一台PHP服务器CPU占用高的问题,但是通过这种方法无效,经过google搜索,发现可以通过下面的方法进行解决,那就尝试下吧。

    解决过程:
    1,根据top命令,发现PID为2633的Java进程占用CPU高达300%,出现故障。
    2,找到该进程后,如何定位具体线程或代码呢,首先显示线程列表,并按照CPU占用高的线程排序:
    [root@localhost logs]# ps -mp 2633 -o THREAD,tid,time | sort -rn
    显示结果如下:
    USER     %CPU PRI SCNT WCHAN  USER SYSTEM   TID     TIME
    root     10.5  19    - -         -      -  3626 00:12:48
    root     10.1  19    - -         -      -  3593 00:12:16
    找到了耗时最高的线程3626,占用CPU时间有12分钟了!
    将需要的线程ID转换为16进制格式:
    [root@localhost logs]# printf "%x " 3626
    e18
    最后打印线程的堆栈信息:
    [root@localhost logs]# jstack 2633 |grep e18 -A 30
    将输出的信息发给开发部进行确认,这样就能找出有问题的代码。
    通过最近几天的监控,CPU已经安静下来了。

     问题分析:
    1,程序属于CPU密集型,和开发沟通过,排除此类情况。
    2,程序代码有问题,出现死循环,可能性极大。

     Java程序很耗CPU是比较好分析的,有这么几步:

    1、先通过top命令找到消耗cpu很高的进程id假设是123

    2、执行top -p 123单独监控该进程

    3、在第2步的监控界面输入H,获取当前进程下的所有线程信息

    4、找到消耗cpu特别高的线程编号,假设是123

    5、执行jstack 123456对当前的进程做dump,输出所有的线程信息

    6 将第4步得到的线程编号11354转成16进制是0x7b

    7 根据第6步得到的0x7b在第5步的线程信息里面去找对应线程内容

    8 解读线程信息,定位具体代码位置
    不一定一次就能抓准线程状态,可以第1步时多记几个线程。

     
     
    我们使用jdk自带的jstack来分析。当linux出现cpu被java程序消耗过高时,以下过程说不定可以帮上你的忙:
    1.top查找出哪个进程消耗的cpu高 
    21125 co_ad2    18   0 1817m 776m 9712 S  3.3  4.9  12:03.24 java                                                                                           
    5284 co_ad     21   0 3028m 2.5g 9432 S  1.0 16.3   6629:44 java                                                                                           
    21994 mysql     15   0  449m  88m 5072 S  1.0  0.6  67582:38 mysqld                                                                                         
    8657 co_sparr  19   0 2678m 892m 9220 S  0.3  5.7 103:06.13 java
    这里我们分析21125这个java进程。 

    2.top中shift+h查找出哪个线程消耗的cpu高 
    先输入top -p 21125,然后再按shift+h。这里意思为只查看21125的进程,并且显示线程。 
    21233 co_ad2    15   0 1807m 630m 9492 S  1.3  4.0   0:05.12 java                                                                                           
    20503 co_ad2_s  15   0 1360m 560m 9176 S  0.3  3.6   0:46.72 java                                                                                           
    21134 co_ad2    15   0 1807m 630m 9492 S  0.3  4.0   0:00.72 java                                                                                           
    22673 co_ad2    15   0 1807m 630m 9492 S  0.3  4.0   0:03.12 java
    这里我们分析21233这个线程,并且注意的是,这个线程是属于21125这个进程的。 

    3.将需要的线程ID转换为16进制格式:
    duanxz@duanxz-pc MINGW64 /d/ebook/spring
    $ printf "%x
    " 21233
    52f1
    4.jstack查找这个线程的信息 
    jstack [进程]|grep -A 10 [线程的16进制] 
    即: 
    jstack 21125|grep -A 10 52f1
    -A 10表示查找到所在行的后10行。21233用计算器转换为16进制52f1,注意字母是小写。 
    结果: 
        "http-8081-11" daemon prio=10 tid=0x00002aab049a1800 nid=0x52f1 in Object.wait() [0x0000000042c75000]  
           java.lang.Thread.State: WAITING (on object monitor)  
             at java.lang.Object.wait(Native Method)  
             at java.lang.Object.wait(Object.java:485)  
             at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:416)  
    说不定可以一下子定位到出问题的代码。
     

    也可以用useful-shells

    原文:https://github.com/oldratlee/useful-shells

    把平时有用的手动操作做成脚本,这样可以便捷的使用。

    show-busy-java-threads.sh

    在排查JavaCPU性能问题时,找出Java进程中消耗CPU多(top us值过高)的线程,查看它的线程栈,从而找出有性能问题的方法调用。

    $ ./show-busy-java-threads.sh 
    The stack of busy(57.0%) thread(23355/0x5b3b) of java process(23269) of user(admin):
    "pool-1-thread-1" prio=10 tid=0x000000005b5c5000 nid=0x5b3b runnable [0x000000004062c000]
       java.lang.Thread.State: RUNNABLE
        at java.text.DateFormat.format(DateFormat.java:316)
        at com.xxx.foo.services.common.DateFormatUtil.format(DateFormatUtil.java:41)
        at com.xxx.foo.shared.monitor.schedule.AppMonitorDataAvgScheduler.run(AppMonitorDataAvgScheduler.java:127)
        at com.xxx.foo.services.common.utils.AliTimer$2.run(AliTimer.java:128)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
  • 相关阅读:
    Leetcode 191.位1的个数 By Python
    反向传播的推导
    Leetcode 268.缺失数字 By Python
    Leetcode 326.3的幂 By Python
    Leetcode 28.实现strStr() By Python
    Leetcode 7.反转整数 By Python
    Leetcode 125.验证回文串 By Python
    Leetcode 1.两数之和 By Python
    Hdoj 1008.Elevator 题解
    TZOJ 车辆拥挤相互往里走
  • 原文地址:https://www.cnblogs.com/brucebai/p/15179238.html
Copyright © 2011-2022 走看看