java初级问题定位之top&jstack

2018-03-11  本文已影响72人  铁拳阿牛

前两天有朋友想了解一下排查问题的时候的技巧,我也是在网上和在工作中看见大神们操作偷学的。服务器上出问题。出现问题的时候,该怎么排查呢?

毫无疑问思路肯定是 Cpu,内存,磁盘,网络,今天的例子就只到了cpu。不过导致这些问题的绝大多数情况都是代码,所以找出来的目的是为了优化代码。
首先上去一个命令肯定是jps(你是环境中的java来跑的情况下) ,看看跑了那些进程,然后就是top了,找到最高使用率的cpu。写了个测试代码

/**
 * @author 铁拳阿牛
 * @createTime 2018/2/28 下午6:31
 **/
public class Test {

    public static void main(String[] args) {
        Object o = new Object();
        for(int i =0 ;i < 100000; i++){
            try{
                if(i== 1000){
            i = 0;
                    System.out.println(i); //反复打应0
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

然后top 命令下看到cpu 100%(Cpu 可以超过100%我这里只有一个main线程,所以最多跑在一个核心上。这个值是多核心的累加值),记住这个线程 PID。


top.png

然后输入下一个命令 top -Hp PID (上图是25882)然后出现下图。可以很明确的知道,有一个线程跑在这里使用了非常高的Cpu.


top-hp.png

接下来你需要去查看线程栈看看,到底是为什么cpu这么高。
你我喜欢 jstack PID > PID_stack.txt 这样来看。(要还是快速排查的时候还是 jstack PID | grep -A (16进制的PID)),然后打印出来查看栈,可以看到

jstack.png
//Test.main(Test.java:9) 然后去看看着个代码干了啥。
"main" #1 prio=5 os_prio=0 tid=0x00007f9b24009000 nid=0x651b runnable [0x00007f9b28ec5000]
   java.lang.Thread.State: RUNNABLE
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:326)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    - locked <0x00000000c441e470> (a java.io.BufferedOutputStream)
    at java.io.PrintStream.write(PrintStream.java:482)
    - locked <0x00000000c4408f30> (a java.io.PrintStream)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
    - locked <0x00000000c4408ee8> (a java.io.OutputStreamWriter)
    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
    at java.io.PrintStream.newLine(PrintStream.java:546)
    - eliminated <0x00000000c4408f30> (a java.io.PrintStream)
    at java.io.PrintStream.println(PrintStream.java:737)
    - locked <0x00000000c4408f30> (a java.io.PrintStream)
      at Test.main(Test.java:9)

这样初级问题就很容易定位出来了。

如果你的 线程id在最下面,比如这样:

"VM Thread" os_prio=0 tid=0x00007f9b24077000 nid=0x6520 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f9b2401e000 nid=0x651c runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f9b24020000 nid=0x651d runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f9b24021800 nid=0x651e runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f9b24023800 nid=0x651f runnable

"VM Periodic Task Thread" os_prio=0 tid=0x00007f9b240cc800 nid=0x6528 waiting on condition

JNI global references: 9

这样就需要别的命令排查了,你可以去看看你假笨的文章或者给我留言,有空写一个。


下面是广告可以关了,关注你假笨的,近期有新玩意哦。

关注阿牛的公众号,从小菜比到老菜比

image

你假笨

image

欢迎关注spring4all

image
上一篇 下一篇

猜你喜欢

热点阅读