先考察Linux操作系统上显示的性能指标,主要关注CPU、Memory、I/O三方面:
主要考察CPU的负载均值(Load Average), CPU 使用率,上下文切换次数(Context Switch)。
top命令–查看平均负载和CPU使用率
直接输入top,进入基本视图
第一行: 这里使用uptime命令也能看到同样的数据
10:01:23 当前系统时间
126 days, 14:29 系统已经运行了126天14小时29分钟(在这期间没有重启过)
2 users 当前有2个用户登录系统
load average: 1.15, 1.42, 1.44 这三个数分别是1分钟、5分钟、15分钟的负载情况。
负载均值就好比行车过桥的车流量
0.00 表示桥面上没有车流,0.00~1.00之间表示很通畅
1.00 表示刚好在桥的承受范围内,不过之后就会越来越堵,越大越糟糕。
0.70 这是理想的值
5.00 这个值出现时就要失眠了,然后等着做报告吧
第二行:任务
Tasks 任务(进程),总共x个,运行中x个,休眠x个,停止x个,僵尸x个
第三行:CPU使用率
6.7% us 用户空间占用CPU的百分比。
0.4% sy 内核空间占用CPU的百分比。
0.0% ni 改变过优先级的进程占用CPU的百分比
92.9% id 空闲CPU百分比
0.0% wa IO等待占用CPU的百分比
0.0% hi 硬中断(Hardware IRQ)占用CPU的百分比
0.0% si 软中断(Software Interrupts)占用CPU的百分比
第四行:内存
8306544k total 物理内存总量(8GB)
7775876k used 使用中的内存总量(7.7GB)
530668k free 空闲内存总量(530M)
79236k buffers 缓存的内存量 (79M)
第五行:swap交换分区
2031608k total 交换区总量(2GB)
2556k used 使用的交换区总量(2.5M)
2029052k free 空闲交换区总量(2GB)
4231276k cached 缓冲的交换区总量(4GB)
第四行的used内存总量是纳入内核管理的内存总量,并不是真正在用的,内核不会把用过的内存还给free。剩余可用内存近似等于free + buffers + cached(swap的)
swap要注意used是否不断变化,意味内存和swap不断交换,内存真正不够用了。
vmstat命令–查看CPU上下文切换频次
vmstat 1 10 (数字表示命令执行频率和频次,1则每秒打印一次,执行10次),内容如下
procs ———–memory———- —swap– —–io—- -system— —cpu—-
r b swpd free buff cache si so bi bo in cs us sy id wa
Procs(进程)
字符列 | 描述 | 意义 |
---|---|---|
r | 在就绪状态等待的进程数 | 如果这个数字超过CPU数量就要注意了! |
b | 在等待状态等待的进程数 | 说白了就是阻塞状态的进程数,比CPU数目高肯定有问题 |
Memory(内存)
字符列 | 描述 | 意义 |
---|---|---|
swpd | 已使用虚拟内存大小 | 如果大于0就表示你的机器物理内存不足了(真的不足还是内存泄露?) |
free | 空闲的物理内存的大小 | |
buff | 存储目录内容,权限等的缓存 | |
cache | cache直接用来存储打开文的缓冲 | sync后,使用echo 1(2,3) > /proc/sys/vm/drop_caches分别进行释放吧! |
Swap(交换区)
字符列 | 描述 | 意义 |
---|---|---|
si | 每秒从磁盘读入虚拟内存的大小 | 如果这个值大于0,表示物理内存不够用或者内存泄露了 |
so | 每秒虚拟内存写入磁盘的大小 | 如果这个值大于0,同上。一般情况下,si、so的值都为0,如果si、so的值长期不为0,则表示系统内存不足,需要增加系统内存 |
IO(输入输出)
字符列 | 描述 | 意义 |
---|---|---|
bi | 块设备每秒接收的块数量 | 这里的块设备是指系统上所有的磁盘和其他块设备 |
bo | 块设备每秒发送的块数量 | 例如:我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就意味着IO操作过于频繁,需要进行调整。 |
System(系统)
字符列 | 描述 | 意义 |
---|---|---|
in | 每秒CPU的中断次数,包括时间中断 | 中断太多了肯定有问题 |
cs | 每秒上下文切换次数 | 这个越小越好。太大了,要考虑调低线程或者进程的数目,例如在apache服务器中,做性能测试时会进行几千并发甚至几万并发的测试,这时就要设置合适的进程数。系统层面的调用也是同样的道理。CS值过大表示上下文切换过于频繁,会消耗很多资源(CPU浪费在上下文切换没有充分利用) |
CPU
字符列 | 描述 | 意义 |
---|---|---|
us | 用户CPU时间(百分比)。 | |
sy | 系统CPU时间(百分比) | 如果太高,表示系统调用时间长,例如是IO操作频繁。 us+sy的参考值为80% |
id | 空闲CPU时间(百分比) | 一般来说,id + us + sy = 100 |
wt | 等待IO的CPU时间(百分比) | 过大就意味着CPU和IO操作需要调整。 wt参考值35% |
vmstat 可以用来确定一个系统的工作是受限于CPU还是受限于内存:如果CPU的sy和us值相加的百分比接近100%,或者运行队列(r) 中等待的进程数总是不等于 0,则该系统受限于CPU;如果pi、po的值总是不等于0,则该系统受限于内存。
上下文切换次数发生的场景主要有如下几种:
1)时间片用完,CPU 正常调度下一个任务;2)被其它优先级更高的任务抢占;3)执行任务碰到 I/O 阻塞,挂起当前任务,切换到下一个任务;4)用户代码主动挂起当前任务让出 CPU;5)多任务抢占资源,由于没有抢到被挂起;6)硬件中断。
经前文的介绍,top, vmstat均可用来查看内存情况
iostat命令–对系统的磁盘操作活动进行监视。能汇报磁盘活动统计情况,也会汇报出CPU使用情况
avg-cpu: %user %nice %system %iowait %steal %idle
8.30 0.02 5.07 0.17 0.00 86.44
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 22.73 43.70 487.42 674035705 7517941952
sda1 0.00 0.00 0.00 2658 536
sda2 0.11 3.74 3.51 57721595 54202216
sda3 0.98 0.61 17.51 9454172 270023368
sda4 0.00 0.00 0.00 6 0
sda5 6.95 0.12 108.73 1924834 1677123536
sda6 2.20 0.18 31.22 2837260 481488056
sda7 12.48 39.04 326.45 602094508 5035104240
%util: 一秒中有百分之多少的时间用于 I/O 操作,即被io消耗的cpu百分比
备注:如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明I/O 队列太长,io响应太慢,则需要进行必要优化。如果avgqu-sz比较大,也表示有当量io在等待。
诊断出性能问题后,就能看出是哪个应用引起的?如果是java应用还需进一步定位到线程乃至某个函数。借助top和jstack可以轻松定位到函数。
top -Hp pid -H 可以显示进程下各线程的情况,其中可获取到有问题的线程id
比如top -Hp 405,得知408线程cpu消耗大。
通过printf “%x\n” 408,这个线程id转成16进制数198
jstack 405 | grep 198
利用jstack命令获取线程的堆栈信息,看线程在哪里阻塞了。可定位到阻塞的对象,在通过代码查找,可定位到具体函数。
具体可参照这篇文章
JVM调优之jstack找出最耗cpu的线程并定位代码