通常情况下,性能报告中只说CPU使用率高的时候,并不能帮助定位问题。因为CPU高会有多种不同的情况。CPU有五种状态(us sy id wa st), 在vmstat中能显示出来,这个想必很多人都清楚。在代码消耗CPU的时候(这也是通常性能分析中会遇到的),是US状态的CPU。当然还存在一种情况,就是代码产生的系统调用特别高,这种情况下SY的CPU也会高(这种情况比较少见,在我的职业生涯中只见过一次)。对于JAVA语言来说,我们不需要特别复杂的profile工具就可以做到定位到代码。

在写具体的分析方法之前,需要说一下线程的状态转换关系,我们先来看一下系统级的线程状态转换关系。

通过这个转换关系,可以看到,在线程产生之后,会先到ready的状态。在这个状态上是在等待CPU的。而在runing状态才是真正在CPU上执行的。请注意这个区别。

而vmstat显示的 r 列是包括了ready和running的线程(会因操作系统的不同有区别,但是对大部分linux系统都是这样)。请注意这一点,因为网上有很多在写vmstat的解释的时候,说 r 列是表示正在运行的进程数或者说 r 是表示正在运行的线程数,这一点是不对的。给大家看一个例子(这也是下面要说到的例子):

这是我的一个云服务器上正在运行的top。可以看到当前tasks(进程)中只有一个是running的状态的。而这时的vmstat呢?

这个服务器只有两个CPU,所以如果r是说正在运行的进程或线程数的话肯定是不正确的,因为两个CPU同时运行的最多是两个线程。

所以请记住,这个 r 值就包括了等待CPU的线程(也就是ready状态的)和正在运行的线程(也就是running状态的)。

以后有时间再解释其他系统级的线程状态,可能有些人觉得其他状态也没什么好解释的,但是在性能分析中,线程的状态和一些性能计数器是有关联关系的,比如说suspended状态是CPU时间片用完导致暂时被换出;而blocked是因为要等待某个条件被满足而阻塞;并且这两种状态都有可能导致CPU使用率高。在分析的过程中,这些信息给我们的是一个方向。所以前面说到仅说CPU高不能帮助分析问题,因为CPU高有多种原因。

因为下面要说的是JAVA,所以来看一下JAVA的线程状态转换关系。

从这个图中,我们可以看到JAVA的进程有多种状态(具体状态的解释请自行搜索),怎么看到这些状态都在干什么,就需要把栈打出来看。在栈中,可以看到具体对应的代码(对其他编译语言来说,要看看到正在运行的code也是要看栈的)。另外,在性能分析中,栈的分析是非常重要的一块内容,今天因为只是为了说明从CPU高怎么定位到代码层,所以不过多解释线程的状态了,以后有时间再写文章说明。

实例:

下面来操作一下,首先执行一个消耗CPU的JAVA实例(实例是7D Group成员所编,有兴趣动手操作的可以到网上随便找一个小例子或自己编写一个)。查看vmstat的状态。

从上图可以看到左边窗口在执行一个消耗CPU的Demo,而右边的窗口看到当前系统的CPU已经完全被消耗掉了。进程号通过top命令就可以知道:

下面就要看一下这个进程中的哪些线程消耗了CPU。

通过pidstat可以看到(不好意思的是,pidstat的截图被我覆盖掉了,又不想重新开始所以就不截图啦),有10个线程消耗着CPU资源。我把命令放在这里,有兴趣的可以自己操作。

pidstat -p 10846 -u -d -t -w -h 1 1000

从上命令可以看到,有多个线程消耗着CPU。线程ID是:10861、10862、10863等等。

用jstack做一下thread dump。

[root@7dgroup ~]# jstack -l 10846 > 10846.threaddump

再打开这个生成的文件。

nid是指native ID,对应着系统级的tid。只不过TID显示的是10进程的,NID显示的是16进制的。

我们转换一个线程号来查找。

[root@7dgroup ~]# printf %x'\n' 10861

2a6d

再对应到threaddump文件中。

显然可以去查这个CPUTestThreadDemo.java的第13行了。

从这个例子可以看出,对java的代码消耗CPU高的分析只需要通过系统级的命令和JDK自带的命令就可以完成了。因为这个例子非常简单,步骤比较清楚。但在实际分析代码众多,逻辑复杂的应用,有可能你看到的是CPU在线程上的消耗是在不停的切换的,所以就需要多做些thread dump,一个个分析。当然借助些工具分析,通常可以让我们在分析复杂的应用时事半功倍。

这里只说明一个思路。

对JAVA的分析来说,已经有非常多的人写了非常多的文章了,我之所以写这个文章,是为了让文章能更系列一些。

  •  
     
     
 

性能分析之CPU分析-从CPU调用高到具体代码行(JAVA)的更多相关文章

  1. 性能分析之CPU分析-从CPU调用高到具体代码行(C/C++)

    今天在培训的过程中,也提到了分析要具体到代码的事情,如果思路方向是正确的,对java应用和C/C++应用来说,也是几个命令就可以跳到代码行了.前提是要能看得懂堆栈信息.所以一直以来我在讲课的过程中都有 ...

  2. Python 获取被调用函数名称,所处模块,被调用代码行

    获取被调用函数名称,所处模块,被调用代码行 by:授客 QQ:1033553122 module2.py: #!/usr/bin/env python # -*- coding:utf-8 -*- _ ...

  3. PC虚拟现实应用的性能分析与优化:从CPU角度切入

    如今,虚拟现实 (VR) 技术正日益受到欢迎,这主要得益于遵循摩尔定律的技术进步让这一全新体验在技术上成为可能.尽管虚拟现实能给用户带来身临其境般的超凡体验,但相比传统应用,其具有双目渲染.低延迟.高 ...

  4. DIY Ruby CPU 分析——Part I

    [编者按]原文作者 Emil Soman,Rubyist,除此之外竟然同时也是艺术家,吉他手,Garden City RubyConf 组织者.本文是DIY Ruby CPU Profiling 的第 ...

  5. DIY Ruby CPU 分析——Part III

    [编者按]作者 Emil Soman,Rubyist,除此之外竟然同时也是艺术家,吉他手,Garden City RubyConf 组织者.本文是 DIY Ruby CPU Profiling 的第二 ...

  6. DIY Ruby CPU 分析 Part II

    [编者按]作者 Emil Soman,Rubyist,除此之外竟然同时也是艺术家,吉他手,Garden City RubyConf 组织者.本文是 DIY Ruby CPU Profiling 的第二 ...

  7. 使用ANTS Performance Profiler&ANTS Memory Profiler工具分析IIS进程内存和CPU占用过高问题

    一.前言 最近一段时间,网站经常出现两个问题: 1.内存占用率一点点增高,直到将服务器内存占满. 2.访问某个页面时,页面响应过慢,CPU居高不下. 初步判断内存一点点增多可能是因为有未释放的资源一直 ...

  8. linux概念之cpu分析

    http://ilinuxkernel.com/?cat=4 Linux CPU占用率原理与精确度分析1  CPU占用率计算原理在Linux/Unix 下,CPU 利用率分为用户态.系统态和空闲态,分 ...

  9. jstack来分析。当linux出现cpu被java程序消耗过高时

    我们使用jdk自带的jstack来分析.当linux出现cpu被java程序消耗过高时,以下过程说不定可以帮上你的忙: 1.top查找出哪个进程消耗的cpu高 21125 co_ad2    18   ...

随机推荐

  1. jquery里面.length和.size()有什么区别

    区别: 1.针对标签对象元素,比如数html页面有多少个段落元素<p></p>,那么此时的$("p").size()==$("p").l ...

  2. java8中的日期和时间API

    一.背景 jdk 1.8 之前, Java 时间使用java.util.Date 和 java.util.Calendar 类. Date today = new Date(); System.out ...

  3. 网络层协议及ARP攻击

    一:网络层介绍及ICMP协议 1,网络层 网络层位于OSI参考模型的第三层,位于传输层和数据链路层之间.向传输层提供最基本的端到端的数据传送服务.定义了基于IP协议的逻辑地址,连接不同媒介类型,选择数 ...

  4. FreeSWITCH的安装与使用

    FreeSWITCH

  5. CSS filter 有哪些神奇用途

    背景 基本概念 CSS filter 属性将模糊或颜色偏移等图形效果应用于元素形成滤镜,滤镜通常用于调整图像,背景和边框的渲染.它的值可以为 filter 函数 <filter-function ...

  6. java集合类介绍

    目录 集合类简介 List ArrayList LinkedList Vector Stack Set HashSet LinkedHashSet TreeSet Map HashMap Hashta ...

  7. Azure DevOps(一)利用Azure DevOps Pipeline 构建应用程序镜像到AWS ECR

    一,引言 最近项目上让开始学习AWS,作为一名合格的开发人员,当然也是学会利用Azure DevOps Pipeline 将应用程序部署到 AWS ECS(完全托管的容器编排服务).我们要学会将应用程 ...

  8. [bug] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full

    原因 lib文件缺失 参考 https://blog.csdn.net/weixin_41060905/article/details/86911172

  9. [Java] HOW2J(Java中级)

    异常 定义:导致程序正常流程被中断的事件 异常处理常见手段 try catch:将可能抛出异常的代码放在try的块中,一旦出现异常就跳转到catch的块中处理 throws/throw:不在本模块处理 ...

  10. linux下dmidecode命令获取硬件信息

    linux下dmidecode命令获取硬件信息 2 A+ 所属分类:Linux 运维工具 dmidecode在 Linux 系统下获取有关硬件方面的信息.dmidecode 遵循 SMBIOS/DMI ...