目前常用的操作系统分为:windows,Unix(Linux),我们会分别介绍在不同系统上的调优。

一,概念

性能监控:一种以非侵入方式收集或查看应用运行性能数据的活动,通常是指在生产,质量评估, 开发环境中实施的带有预防或主动性的活动。

性能分析:一种以侵入方式收集运行性能数据的活动,会影响应用的吞吐量或响应性。

性能调优:一种为改善应用响应性或吞吐量而更改参数,源代码或属性配置的活动。

CPU:中央处理器,从内存中获取数据然后进行计算的处理单元,

CPU使用率:分为用户态CPU使用率和系统态CPU使用率,用户态CPU使用率是指执行应用程序代码的时间占总CPU时间的百分比,系统态CPU指应用执行操作系统调用的时间占用总CPU的时间的百分比。例如I/O设备之间的交互教师使用系统态CPU,所以我们想要的结果是系统态的CPU的使用率为0%,即降低系统态CPU的使用率

CPI:(Cycle Per instruction):每条指令执行时所花费的平均时钟周期数。(时钟周期:也为震荡周期,定义为时钟脉冲的倒数,是计算机中最基本,最小的时间单位,在一个时钟周期内,CPU仅完成一个最基本的动作,例如1MHZ的时钟频率,则时钟周期为1us,对计算机来说,时钟频率越高,计算机的工作速度就越快)(指令周期:执行一条指令所需的时间,指令不同,所需的周期数也不同)。

二,监控CPU的使用率:

WINDOWS:

任务管理器

上面有CPU的使用率,内存的使用率,进程数,线程,CPU的执行速度等

Performance Monitor(性能监视器)

不同版本的WINDOWS上的性能监视器是不同的,性能监视器使用了性能对象的概念,性能对象分为网络,内存,处理器,线程,进程,网络接口,逻辑磁盘等,每一类都含有特定的性能属性或计数器。可以作为监控的性能统计数据。

红线表示进程信息,性能监视器的滑动串口默认显示最近60秒的性能统计数据,可在图形界面点击右键,设置一些属性。

可以手动的添加各种性能对象,通过在图像区域点击右键-》选择添加计数器-》选择计数器Processor对象,选择计数器%User time表示用户态CPU使用率,选择计数器%Privileged Time表示系统态CPU使用率,点击Add -》确定。

命令行工具:typeperf

typeperf可以在命令终端运行,也可以写在脚本语句中,写法:

typeperf "\Processor(_Total)\%User Time" 

Linux:

监控命令:

gnome-system-monitor:

vmstat:

[land@localhost network-scripts]$ 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  60936  81388     36 203572    1   11   211    13  116  123  0  1 96  2  0

vmstat显示所有虚拟处理器的总CPU使用率,vmstat命令行可以设定报告的时间间隔,如果不指定vmstat的报告间隔,则输出系统最近一次启动以来的总CPU的使用率。us是用户态CPU使用率,sy是系统态CPU使用率,id是空闲率或CPU可用率。

mpstat:

[land@localhost network-scripts]$ mpstat
Linux 3.10.0-862.el7.x86_64 (localhost.localdomain) 	12/12/2018 	_x86_64_	(4 CPU)

03:33:50 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
03:33:50 AM  all    0.42    0.00    0.86    2.06    0.00    0.04    0.00    0.00    0.00   96.62

top命令:

不仅包括CPU的使用率,也包括进程统计数据和内存使用率,

CPU的调度程序运行队列

监控CPU调度程序运行队列对于分辨系统是否满负荷有很重要的意义,运行队列中就是已经准备好运行,正在等待可用CPU的轻量级进程。如果准备运行的进程数量过多,就是导致调度队列过长,则系统有可能已经饱和。

一般原则:如果在很长一段时间里,运行队列的长度一直都超过虚拟处理器个数的1倍,就需要注意,如果运行队列的长度超多虚拟处理器个数的3-4倍或更高,则需要立刻采取行动。

解决队列过长的两种方法:⑴增加CPU以分担负载或减少处理器的负载量⑵分析系统中运行的应用,改进CPU使用率,即减少应用运行所需CPU周期的方法,如减少垃圾收集器的频率,或使用更少的CPU指令算法来实现相同的功能。

WINDOWS:

通过在性能监视器图中-》右键-》添加计数器-》system->Processor Queue Length-》确定。

当然也可以使用typeperf命令来监视运行队列的长度。

Linux:

使用vmstat命令可以监控运行队列的长度,vmstat输出的第一列是运行队列长度,值是运行队列中轻量级进程的实际数量。

[land@localhost ~]$ 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  43528  61980     36 240280    0    9   271    21   96   91  0  1 96  2  0

监控锁竞争:

Java5以上的锁优化机制。线程通过忙循环自旋尝试获取锁,如果若干次忙循环自旋后仍然没有成功,则挂起该线程,等待被唤醒再次尝试获取该锁。挂起和唤醒线程会导致操作系统的让步式上下文切换,因此锁竞争严重的应用程序会表现出大量的让步式上下文切换,Solaris上可以通过mpstat的csw列监控上下文切换,它是上下文切换的总和。icsw列是抢占式上下文切换,因此让步式上下文切换的次数是csw-icsw.让步式上下文切换耗时的时钟周期代价非常高,通常高达80000个时钟周期。

对于任何Java应用来说,如果让步式上下文切换占去它5%或者更过时钟周期,说明可能遇到锁竞争,估算让步式上下文切换:mpstat间隔内的线程上下文csw减去抢占式上下文(icsw),乘80000,除以间隔内总的时间周期。

监控网络I/O使用率:

WINDOWS:

在性能监视器中,通过添加性能计数器就可以,性能对象为Network Interface/Bytes Total/sec获得,通配符*表示报告的是系统所有网络接口的总带宽。也可以使用typeperf \Network Interface(*)\Bytes Total/sec查看网络接口名。然后用想要打算监控的网络接口替换通配符*。

查看网络带宽可以添加Network Interface/Current Bandwidth对象,查看网络的带宽

硬盘I/O的使用率:

硬盘I/O可以看做是磁盘使用情况有用的监控数据,Linux和Solaris可以使用iostat来监控系统的磁盘使用情况。Linux可以使用iostat -xm监控磁盘I/O使用率和系统态CPU使用率。

[root@localhost ~]# iostat -xm 
Linux 3.10.0-862.el7.x86_64 (localhost.localdomain) 	12/12/2018 	_x86_64_(4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.36    0.00    0.80    2.08    0.00   96.76

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.87     9.86   20.22    0.64     1.06     0.05   109.22     0.53   25.25   25.48   18.06   3.41   7.12
scd0              0.00     0.00    0.02    0.00     0.00     0.00    72.41     0.00   49.83   49.83    0.00  40.90   0.07
dm-0              0.00     0.00   19.85    0.56     1.05     0.01   106.59     0.53   25.84   26.25   11.10   3.44   7.03
dm-1              0.00     0.00    1.04    9.94     0.01     0.04     8.21     0.58   52.69   11.14   57.03   0.27   0.30

[root@localhost ~]# 

sda磁盘的使用率为 7.12%,系统态CPU为0.8%,用户态CPU0.36%。

 

参考《Java 性能优化权威指南》    Charlie Hunt  Binu John 著