确定性能问题

OS 诊断

先考察Linux操作系统上显示的性能指标,主要关注CPU、Memory、I/O三方面:

CPU 诊断

主要考察CPU的负载均值(Load Average), CPU 使用率,上下文切换次数(Context Switch)。

top命令–查看平均负载和CPU使用率

直接输入top,进入基本视图

linux 调整javaheap大小 linux调整jvm参数_性能

第一行: 这里使用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)硬件中断。

Memory 诊断

经前文的介绍,top, vmstat均可用来查看内存情况

IO 诊断

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 应用诊断

诊断出性能问题后,就能看出是哪个应用引起的?如果是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的线程并定位代码