java性能分析--基于操作系统的分析之cpu

322 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

关于标题的含义,其实源于性能分析的起点,操作系统本身的分析工具,它与java本身无关。我们在分析一个系统性能的时候,首先应该关注系统的CPU内存磁盘网络等,这是我们分析性能问题的起点,通过操作系统的提供的工具就能直观的告诉我们这些指标。

CPU使用率

CPU使用率应该是我们在服务器最先查看的命令,比如当我使用top -H命令,查看线程占用CPU的百分比,会得到如下内容:

top - 14:46:54 up 88 days, 1 min,  2 users,  load average: 0.00, 0.01, 0.05
Threads: 237 total,   1 running, 236 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.0 us,  1.3 sy,  0.0 ni, 97.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3879808 total,   593156 free,  1584680 used,  1701972 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  2025080 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                             
23168 root      20   0  157836   6348   4664 S  0.7  0.2   0:00.07 sshd                                                                                                                
  411 root      16  -4   55532   1080    632 S  0.3  0.0   0:03.29 auditd                                                                                                              
 7938 root      20   0 1198484  15800   7752 S  0.3  0.4  14:44.29 hostguard                                                                                                           
20669 mysql     20   0 1851860 503640  18500 S  0.3 13.0   4:06.97 ib_src_main                                                                                                         
    1 root      20   0  191056   4000   2616 S  0.0  0.1   0:24.22 systemd                                                                                                             
    2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd                                                                                                            
    4 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0H                                                                                                        
    6 root      20   0       0      0      0 S  0.0  0.0   0:02.10 ksoftirqd/0                                                                                                         
    7 root      rt   0       0      0      0 S  0.0  0.0   0:07.80 migration/0 

如上所示我们看到当前哪些线程占用较多的CPU和内存,以及当前的内存使用率。

当我们再次键入按键 1 时,可以查看所有的CPU核心的占用数量,我的是2核,如下所示:

image.png

如上图所示,我们发现在每个CPU后面包含一些英文字母,如us、sy、ni等等,那么他们代表什么?下面我来分别讲一下。

如下的单位都是百分比:

  • us: 用户态时间,执行用户应用代码占用时间。
  • sy: 系统态时间,执行内核代码所用时间。系统态时间通常和用户的应用代码还有关联的,比如应用执行IO操作,系统会执行内核代码从磁盘读取文件,抑或者将数据发送到网络IO。使用底层系统操作,都会增加系统太时间。
  • ni:被 nice 命令改变优先级的任务所占用的CPU时间,不细讲,感兴趣自己查资料。
  • id:CPU空闲时所占用时间。
  • wa:在执行的过程中等待IO所占用的时间。
  • hi:硬件中断所占用的时间。
  • si:软件中断所占用的时间。
  • st:翻译为实时的含义,但是听起来还是一脸懵。查阅资料发现有大佬说是作用于虚拟化的时间占有量。比如在服务器上安装虚拟机等。

或者可以使用命令vmstat 1查看,可以得到每秒的cpu使用率:

image.png

如上图红圈中所示内容:

名称占用时间
用户态时间9%
系统态时间2%
等待IO1%
空闲时间88%

发现相加并没有等于百分之百,此处四舍五入,不完全精确。

CPU运行队列

unix系统当中存在运行队列,表示所有正在运行和等待运行的线程数。 如下图所示:

image.png

即我们使用vmstat 1命令时,其中r这一列表示的就是运行队列中的内核线程数。

windows当中与unix不同,不是重点,此处不讲解。

针对这个运行队列,我们可以发现一些问题

通常来说,运行队列中的线程数不能超过cpu的个数,当然不是绝对的,某些瞬间会导致线程数飙高,但是不会造成实质性的影响。

但是如果长时间内的运行队列很长,说明系统可能已经过载了,你的代码可能存在问题,或者需要扩容。

如上图还有一个b开头的列,这一列是等待队列,表示正在等待IO的线程数,如果此列长度很大且长时间占据,那说明系统io很大。

总结

经过前面的学习,应该可以总结几点查看系统性能的关键:

  • 查看CPU时间

  • 查看CPU的运行队列

  • 优化代码其实是提升cpu的使用率,当然,是建立在更短时间段内的。