一、具体步骤

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. 常见面试题整理--Python概念篇

    希望此文可以长期更新并作为一篇Python的面试宝典.每一道题目都附有详细解答,以及更加详细的回答链接.此篇是概念篇,下一篇会更新面试题代码篇. (一).这两个参数是什么意思:*args,**kwar ...

  2. MySQL数据库(1)- 数据库概述、MySQL的安装与配置、初始SQL语句、MySQL创建用户和授权

    一.数据库概述 1.什么是数据(Data) 描述事物的符号记录称为数据,描述事物的符号既可以是数字,也可以是文字.图片,图像.声音.语言等,数据由多种表现形式,它们都可以经过数字化后存入计算机. 在计 ...

  3. Angular学习笔记—RxJS与Observable(转载)

    1. Observable与观察者模式的关系 其实这里讲的Observable就是一种观察者模式,只不过RxJS把Observable结合了迭代模式以及附件了很多的operator,让他变得很强大,也 ...

  4. linux 或c 时间相关处理类型和函数

    注意1.精确级别,纳秒级别原型long  clock_gettime (clockid_t which_clock, struct timespec *tp); 头文件time.hwhich_cloc ...

  5. BCH码

    http://baike.baidu.com/link?url=CfLtm9DigwWdup-9VJP99RG65NgaVOXfrnjT61ogP7au0QOrlypq72k67B0s1Ey-Q1yD ...

  6. 【Flask】Flask Cookie操作

    ### 什么是cookie:在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是为了解决这个问题,第 ...

  7. JVM调优总结(一)

    数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对象本身, ...

  8. 【纯代码】Swift相册照片选择-支持单选或多选

    // // NAPublishAlbumTableViewController.swift //// // Created by on 2019/3/23. // Copyright © 2019年 ...

  9. Dangling Javadoc comment

    Javadoc主要用于对类和方法的注释.Javadoc没有@file和@date的注解.Javadoc has no @file or @date tags. You should be taggin ...

  10. nginx反向代理服务器端口问题

      nginx可以很方便的配置成反向代理服务器 server { listen 80; server_name bothlog.com; location / { proxy_set_header H ...