JVM性能监控与优化笔记(CPU)

基础

对于CPU层面的监控主要以下几个点:

  • 是否系统态CPU的占用率高
  • CPU运行队列中待运行的任务数
  • 是否CPU停滞多,每时钟指令数(IPC)少(高级点,对于计算密集型的应用需要关注)

系统态CPU占用率高意味着共享资源有竞争或者有大量的I/O交互,因为这两类都会导致频繁的线程切换,所以会有大量的操作系统调用。
CPU调度程序运行队列中就是那些已准备好运行,正等待可用CPU的任务数(线程)。运行队列长度等于处理器个数时,不会有明显的性能下降。长度达到处理器个数的1倍时,则需要警惕了。而如果在较长的一段时间内,运行队列的长度达到处理器个数的3~4倍或者更多是,系统相应就会很慢了。
CPU停滞是指执行CPU指令所需的数据不在寄存器或者高速缓存中,需要从内存中调换,这时候就会导致CPU的停滞,但它仍然占用了CPU的时钟周期,所以会显示CPU还是很繁忙。

标准

一般不超出下面指标的情况都可以任务CPU处于合理的运行状态中

  • 运行队列——每个处理器的运行队列不应多于1-3个。例如一个双核处理器的运行队列不应当多于6个进程。
  • CPU利用率——如果CPU充分利用,应该达到一下的平衡比例
    – 65-70%的用户时间
    – 30-35%的系统时间
    – 0-5%的空闲时间
  • 上下文切换——上下文切换的数量直接决定了CPU的利用率。如果CPU利用率保持在上述的平衡比列,那么大量的上下文切换是正常的

监控工具

监控使用率

对于使用率的健康常用的工具有:vmstat,mpstat,top

vmstat

输入如下:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 4710712 369028 1433668    0    0    11    22  380   70 15  3 82  0  0
 0  0      0 4710892 369032 1433764    0    0     0    26  161  361  0  0 99  0  0
 0  0      0 4710768 369040 1433764    0    0     0     8  150  292  0  0 100  0  0

输出的最后一列,即为cpu的占用率。

mpstat

mpstat用于观察多核CPU每一核的状态,同时它包含了更多的输出信息,例如

Linux 3.13.0-43-generic (X230) 	2014年12月14日 	_x86_64_	(4 CPU)

17时24分18秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
17时24分18秒  all   15.03    0.01    3.05    0.02    0.00    0.00    0.00    0.00    0.00   81.89
17时24分18秒    0   11.35    0.02    2.39    0.02    0.00    0.00    0.00    0.00    0.00   86.21
17时24分18秒    1   16.29    0.01    3.24    0.02    0.00    0.00    0.00    0.00    0.00   80.44
17时24分18秒    2   18.19    0.01    3.84    0.01    0.00    0.01    0.00    0.00    0.00   77.95
17时24分18秒    3   16.36    0.01    3.11    0.01    0.00    0.00    0.00    0.00    0.00   80.51

17时24分18秒  CPU    intr/s
17时24分18秒  all    500.49
17时24分18秒    0     36.19
17时24分18秒    1     30.58
17时24分18秒    2     34.01
17时24分18秒    3     30.69

17时24分18秒  CPU        0/s        1/s        8/s        9/s       12/s       16/s       23/s       40/s       41/s       42/s       43/s       44/s       45/s       46/s      NMI/s      LOC/s      SPU/s      PMI/s      IWI/s      RTR/s      RES/s      CAL/s      TLB/s      TRM/s      THR/s      MCE/s      MCP/s      ERR/s      MIS/s
17时24分18秒    0       0.00       0.08       0.00       0.00       0.21       0.17       0.00       0.00       1.32       0.00       0.02      21.08       3.41       0.00       0.00     102.20       0.00       0.00       1.03       0.00      18.50       0.01       1.08       0.00       0.00       0.00       0.00       0.00       0.00
17时24分18秒    1       0.00       0.00       0.00       0.01       0.22       0.07       0.00       0.00       0.37       0.00       0.12       0.00      12.64       0.00       0.00      76.54       0.00       0.00       0.87       0.00      16.62       0.01       0.94       0.00       0.00       0.00       0.00       0.00       0.00
17时24分18秒    2       0.00       0.00       0.00       0.00       0.10       0.24       0.00       0.00       0.40       0.00       0.00       0.01       0.73       0.00       0.00     113.41       0.00       0.00       0.99       0.00      21.63       0.01       1.02       0.00       0.00       0.00       0.00       0.00       0.00
17时24分18秒    3       0.00       0.00       0.00       0.00       0.09       0.43       0.00       0.00       0.50       0.00       0.00       0.00       0.80       0.00       0.00      83.13       0.00       0.00       0.78       0.00      17.68       0.01       0.88       0.00       0.00       0.00       0.00       0.00       0.00

17时24分18秒  CPU       HI/s    TIMER/s   NET_TX/s   NET_RX/s    BLOCK/s BLOCK_IOPOLL/s  TASKLET/s    SCHED/s  HRTIMER/s      RCU/s
17时24分18秒    0       0.17      18.95       0.01       0.04       1.31       0.00       0.25       9.62       0.15       5.69
17时24分18秒    1       0.07      16.35       0.01       0.23       0.37       0.00       0.08       8.38       0.11       4.99
17时24分18秒    2       0.24      18.77       0.01       0.02       0.40       0.00       0.24       8.62       0.14       5.57
17时24分18秒    3       0.43      16.23       0.01       0.01       0.50       0.00       0.43       8.05       0.11       4.92
top

用top查看cpu信息时主要是可以查看每个java线程占用的CPU,再结合jstack的信息,可以发现占用CPU较高的线程,以及该线程当前在做的任务。
输入top命令后,按“H”键,或者直接用top -H启动top,即可按线程查看。

top - 17:37:02 up 23:14,  2 users,  load average: 0.31, 0.18, 0.13
Threads: 495 total,   1 running, 494 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.8 us,  0.6 sy,  0.0 ni, 98.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   7894256 total,  3353116 used,  4541140 free,   370244 buffers
KiB Swap:  8102908 total,        0 used,  8102908 free.  1486564 cached Mem
Locate string 
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                           
 1305 root      20   0  342460  61712  49948 S  2.0  0.8  13:18.28 Xorg                                                                                              
 5840 ronry     20   0  847116  45540  21932 S  2.0  0.6   0:06.96 /usr/bin/termin                                                                                   
 2195 ronry     20   0 1487912  91888  35680 S  0.7  1.2  16:39.39 compiz                                                                                            
    8 root      20   0       0      0      0 S  0.3  0.0   0:03.33 rcuos/0                                                                                           
   39 root      20   0       0      0      0 S  0.3  0.0   0:00.37 ksoftirqd/3                                                                                       
 1227 root      20   0    4368    712    536 S  0.3  0.0   0:07.59 acpid                                                                                             
 7386 ronry     20   0 1478608 128360  63084 S  0.3  1.6   3:17.79 Chrome_IOThread                                                                                   
 7634 root      20   0       0      0      0 S  0.3  0.0   0:01.10 kworker/u16:1                                                                                     
 8152 ronry     20   0   29440   1992   1164 R  0.3  0.0   0:00.10 top                                                                                               
    1 root      20   0   33900   3212   1468 S  0.0  0.0   0:01.39 init                                                                                              
    2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd          

需要注意的是,top的pid是十进制的,与jstack的信息对比时,需要将其转换成16进制,才能找到对应线程的stack信息。

监控CPU调度程序运行队列

监控运行队列的长度使用vmstat命令,命令输出的第一行就是队列的长度。

调优

对于CPU层面的性能问题,一般可以从以下方面入手进行调优:

  • 寻找更高效的算法(减少CPU的计算量)
  • 减少线程切换(I/O等待,资源竞争)

posted on 2014-12-14 22:05  ronry  阅读(493)  评论(0编辑  收藏  举报

导航