一、具体步骤

shift+p 按照cpu排序
shift+m按照内存排序
1、查看进程下所有线程 top -H -p  pid 
2、将十进制数换成16进制:print "%x/n" 线程id
3、查看进程下的线程正在执行的方法:  jstack  pid|grep  0X70d4

以我们最近出现的一个实际故障为例,介绍怎么定位和解决这类问题。

clip_image002

根据top命令,发现PID为28555的Java进程占用CPU高达200%,出现故障。

通过ps aux | grep PID命令,可以进一步确定是tomcat进程出现了问题。但是,怎么定位到具体线程或者代码呢?

首先显示线程列表:

ps -mp pid -o THREAD,tid,time

找到了耗时最高的线程28802,占用CPU时间快两个小时了!

其次将需要的线程ID转换为16进制格式:

printf "%x\n" tid

2

最后打印线程的堆栈信息:

jstack pid |grep tid -A 30

3

找到出现问题的代码了!

现在来分析下具体的代码:ShortSocketIO.readBytes(ShortSocketIO.java:106)

ShortSocketIO是应用封装的一个用短连接Socket通信的工具类。readBytes函数的代码如下:

public byte[] readBytes(int length) throws IOException {

if ((this.socket == null) || (!this.socket.isConnected())) {

throw new IOException("++++ attempting to read from closed socket");

}

byte[] result = null;

ByteArrayOutputStream bos = new ByteArrayOutputStream();

if (this.recIndex >= length) {

bos.write(this.recBuf, 0, length);

byte[] newBuf = new byte[this.recBufSize];

if (this.recIndex > length) {

System.arraycopy(this.recBuf, length, newBuf, 0, this.recIndex - length);

}

this.recBuf = newBuf;

this.recIndex -= length;

} else {

int totalread = length;

if (this.recIndex > 0) {

totalread -= this.recIndex;

bos.write(this.recBuf, 0, this.recIndex);

this.recBuf = new byte[this.recBufSize];

this.recIndex = 0;

}

int readCount = 0;

while (totalread > 0) {

if ((readCount = this.in.read(this.recBuf)) > 0) {

if (totalread > readCount) {

bos.write(this.recBuf, 0, readCount);

this.recBuf = new byte[this.recBufSize];

this.recIndex = 0;

} else {

bos.write(this.recBuf, 0, totalread);

byte[] newBuf = new byte[this.recBufSize];

System.arraycopy(this.recBuf, totalread, newBuf, 0, readCount - totalread);

this.recBuf = newBuf;

this.recIndex = (readCount - totalread);

}

totalread -= readCount;

}

}

}

问题就出在标红的代码部分。如果this.in.read()返回的数据小于等于0时,循环就一直进行下去了。而这种情况在网络拥塞的时候是可能发生的。

至于具体怎么修改就看业务逻辑应该怎么对待这种特殊情况了。

最后,总结下排查CPU故障的方法和技巧有哪些:

1、top命令:Linux命令。可以查看实时的CPU使用情况。也可以查看最近一段时间的CPU使用情况。

2、PS命令:Linux命令。强大的进程状态监控命令。可以查看进程以及进程中线程的当前CPU使用情况。属于当前状态的采样数据。

3、jstack:Java提供的命令。可以查看某个进程的当前线程栈运行情况。根据这个命令的输出可以定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等等。

4、pstack:Linux命令。可以查看某个进程的当前线程栈运行情况。

Java 系统性能分析 命令

1. cpu分析 
top , pidstat(sysstat) 
pid -p PID -t 1 10 
vmstat 1 CPU上下文切换、运行队列、利用率 
ps Hh -eo tid 
pcpu 查看具体线程的CPU消耗 
sar 来查看一定世界范围内以及历史的cpu消耗情况信息

查看java线程信息 
jstack pid | grep 'nid=0x9999'

2. cs sy消耗比较高 
上下文切换性能偏高, jstack -l pid, 查看on object monitor

3. io消耗 
pidstat -d -t -p pid 1 100 
iostat

4. 网络io消耗 
cat /proc/interruptes 
sar -n FULL 1 2

CPU高获取其线程ID然后分析的更多相关文章

  1. 利用进程ID获取主线程ID

    利用进程ID获取主线程ID,仅适用于单线程.多线程应区分哪个是主线程,区分方法待验证 (1)好像可以用StartTime最早的,不过通过线程执行时间不一定可靠,要是在最开始就CreateThread了 ...

  2. 利用jstack命令定位占用cpu高的java线程及具体错误代码信息

    1.先用top查询某进程的线程CPU占用情况,定位到cpu占用高的进程pid 2.根据pid定位具体的线程top -p PID -H ,找出占用cpu最大的pid,此处占用cpu比较平均,我们随便选择 ...

  3. 线程相关函数(2)-pthread_self()获取调用线程ID

    获取调用线程tid #include <pthread.h>pthread_t pthread_self(void); 示例: #include <pthread.h> #in ...

  4. CPU优化上下文切换之线程上下文切换案例分析

    对于线程上下文切换,如果同进程内就是只是线程上下文切换,如果非同进程内则是进程上下文切换.下面进行线程上下文切换场景模拟. 一.环境准备~模拟工具sysbench. 1)安装git yum -y in ...

  5. 获取当前线程id

    转:https://www.cnblogs.com/comsky/p/6020327.html 如果获得当前进程的Id用: Process[] processes = Process.GetProce ...

  6. cpu高占用,线程堆栈,jstack,pstack,jmap, kill -3 pid,java(weblogic,tomcat)

    1 ps -mp pid -o THREAD,tid,time 2 printf "%x\n" tid 3 jstack pid |grep tid -A 30

  7. java进程CPU高分析

    JVM导致系统CPU高的常见场景: 内存不足,JVM gc频繁,一般会伴随OOMJVM某个线程死循环或者递归调用 定位和解决1.内存不足,gc频繁可参考我的这遍文章解决.https://blog.cs ...

  8. linux获取线程ID

    pthread_self()获取当选线程的ID.这个ID与pthread_create的第一个参数返回的相同.但是与ps命令看到的不同,因此只能用于程序内部,用于对线程进行操作. #include & ...

  9. 线程、线程ID获取

    一.进程ID获取 1.1  当前进程的Id 方法1 通过进程名获取 下面的例子中,也包含了获取该进程下的线程的方法. System.Diagnostics.Process[] processes:bo ...

随机推荐

  1. Angular 学习笔记 :初识 $digest , $watch , $apply,浅析用法 。

    传统的浏览器事件循环 :浏览器本身一直在等待事件,并作出响应.如果你点击一个button或者在input 中输入字符,我们在 JS 中 监听这些事件并设定了回调函数,那么这些事件被触发以后,回调函数就 ...

  2. 杭电1022Train Problem I

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=1022 题目: Problem Description As the new term comes, the ...

  3. Linux 进程管理 kill、killall、pkill命令

    Linux常用信号(进程间通信) 系统中可以识别的信号较多,我们可以使用命令"kill -l"或"man 7 signal"来查询.命令如下: [root@lo ...

  4. ddt运行报错AttributeError: type object 'TestLogin' has no attribute 'test_login'

    源代码: #!usr/bin/python3 # -*- coding:utf-8 -*- # @Time: 2018/12/17 下午2:07 # @File: do_excel.py # @Sof ...

  5. nginx日志分割总结

    nginx日志自己不会进行分个,所有日志都会累积的记录在 access.log,error.log 中,当请求量大,一天就能到几百兆,如果不进行分给,对日志的查看和写入性能都有影响. 1. 编写脚本n ...

  6. Cisco、HUAWEI、H3c、Firewall等设备配置snmp

    配置HUAWEI交换机S1720.S2700.S5700.S6720等型号设备的snmp v3配置 注:此配置来源自官方配置文档 操作步骤 配置交换机的接口IP地址,使其和网管站之间路由可达 (图1) ...

  7. Kotlin 卸载APP自身

    package com.example.batdw01.myapplication import android.net.wifi.WifiManager import android.support ...

  8. [BZOJ2815]灾难

    题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过生物的阿米巴告 ...

  9. 编译lineageos

    lineageos 2 -- 编译rom包 fu*k小米,手机老是1年左右出现充不进去电.前段时间我的红米note4x突然充不进去电了,只好新买了个手机(买手机先看lineageos支持列表 ^_^) ...

  10. bzoj 1050: [HAOI2006]旅行comf(codevs.cn 1001 舒适的路线) 快排+并查集乱搞

    没用的话:好像很久没发博客了,主要是懒太蒟找不到水题.我绝对没弃坑...^_^ 还用些话:本文为博主原创文章,若转载请注明原网址和作者. 进入正题: 先pa网址: bzoj :http://www.l ...