性能分析定位方法
CPU瓶颈
内存瓶颈
IO瓶颈
一、CPU瓶颈
- 系统cpu使用率:利用率高可以关注IO是否有非空闲等待(iostat),通常都是因为IO问题,此时的中断和切换都高。
- 用户cpu使用率:top命令查看系统进程和线程ID,如果知道了线程id、dump的线程信息,就可以找到对应程序
1、执行top命令,找出占用资源厉害的java进程id
[图片上传失败...(image-cd38a-1589711767763)]
2、如上图所示,java的进程id为'52554',接下来用top命令单独对这个进程中的所有线程作监视:
top -p 52554 -H
如图:(这时就看出来哪个java线程CPU高,哪个线程内存用的多)
image.png3、如上图所示,pid=9757这个是占用进程52554资源最高的线程,其实也就是tid。
将线程9757的16进制261d,从堆栈信息中抓出来:
jstack -l 261d > stack.log
因为在堆栈信息里线程id都是16进制的,所以最好写个脚本把获取的线程id转化成16进制,这样就不用每次定位问题都要去手动转换了。
脚本jtgrep.sh如下:
#!/bin/sh
dec2hex(){
printf "%x" $1
}
a=$(dec2hex $1)
grep -i $a $2
最后执行./jtgrep 9757 stack.log。就是在推展信息里过滤出9757这个线程的信息。
【这里有个情况要特别说明,如果查看的占用CPU的线程为java gc线程,通常是由于内存快满才导致jvm频繁gc,进而导致CPU高。固此种情况得按内存问题去定位解决。】
二、内存瓶颈
-
获取Java进程id
-
通过jamp命令来dump下Heap信息
jmap -dump:format=b,file=20170307.dump 16048
file后面的是自定义的文件名,最后的数字是进程的pid。 -
通过JVisualvm来分析Heap信息,找到占Heap内存多的对象
-
由对象找到内存回收根节点,就可以定位到程序
【也可以用JVisualvm抽样器-内存】
相关知识点:
image.pngjvm各主要参数的作用如下:
Xms:设置jvm内存的初始大小
-Xmx:设置jvm内存的最大值
-Xmn:设置新域的大小(这个似乎只对 jdk1.4来说是有效的,后来就废弃了)
-Xss:设置每个线程的堆栈大小(也就是说,在相同物理内存下,减小这个值能生成更多的线程)
-XX:NewRatio :设置新域与旧域之比,如-XX:NewRatio = 4就表示新域与旧域之比为1:4
-XX:NewSize:设置新域的初始值
-XX:MaxNewSize :设置新域的最大值
-XX:MaxPermSize:设置永久域的最大值
-XX:SurvivorRatio=n:设置新域中Eden区与两个Survivor区的比值。(Eden区主要是用来存放新生的对象,而两个Survivor区则用来存放每次垃圾回收后存活下来的对象)
https://blog.csdn.net/lingbo229/article/details/82586822
buffer和cache
1.buffer:
A buffer is something that has yet to be "written" to disk.翻译过来就是:buffer就是写入到磁盘。buffer是为了提高内存和硬盘(或其他I/O设备)之间的数据交换的速度而设计的。buffer将数据缓冲下来,解决速度慢和快的交接问题;速度快的需要通过缓冲区将数据一点一点传给速度慢的区域。例如:从内存中将数据往硬盘中写入,并不是直接写入,而是缓冲到一定大小之后刷入硬盘中。
2.cache:
A cache is something that has been "read" from the disk and stored for later use.翻译过来就是:cache就是从磁盘读取数据然后存起来方便以后使用。cache实现数据的重复使用,速度慢的设备需要通过缓存将经常要用到的数据缓存起来,缓存下来的数据可以提供高速的传输速度给速度快的设备。例如:将硬盘中的数据读取出来放在内存的缓存区中,这样以后再次访问同一个资源,速度会快很多。
3.buffer和cache的特点
共性:
都属于内存,数据都是临时的,一旦关机数据都会丢失。
差异:
A.buffer是要写入数据;cache是已读取数据。
B.buffer数据丢失会影响数据完整性,源数据不受影响;cache数据丢失不会影响数据完整性,但会影响性能。
C.一般来说cache越大,性能越好,超过一定程度,导致命中率太低之后才会越大性能越低。buffer来说,空间越大性能影响不大,够用就行。cache过小,或者没有cache,不影响程序逻辑(高并发cache过小或者丢失导致系统忙死除外)。buffer过小有时候会影响程序逻辑,如导致网络丢包。
D.cache可以做到应用透明,编写应用的可以不用管是否有cache,可以在应用做好之后再上cache。当然开发者显式使用cache也行。buffer需要编写应用的人设计,是程序的一部分。
使用jstat命令查看系统gc情况:
jstat -gcutil 2388 3000 6 每隔3秒打印一次pid为2388的堆内存的使用情况,共打印6次。
image.png
S0 — Heap上的 Survivor space 0 区已使用空间的百分比
S1 — Heap上的 Survivor space 1 区已使用空间的百分比
E — Heap上的 Eden space 区已使用空间的百分比
O — Heap上的 Old space 区已使用空间的百分比
P — Perm space 区已使用空间的百分比
YGC — 从应用程序启动到采样时发生 Young GC 的次数
YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒) FGC — 从应用程序启动到采样时发生 Full GC 的次数
FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒) GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)
Full GC执行占比=(测试结束FGCT总时间-测试开始FGCT总时间)/(测试结束时间-测试开始时间)
Full GC执行间隔=(测试结束时间-测试开始时间)/(测试结束FGC次数-测试开始FGC次数)
三、IO瓶颈
- 网络IO:
nload监控网络的带宽、netstat连接数和连接状态:
查看tcp连接数状态:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
统计8080端口上有多少个TCP连接:netstat -ant |grep 80|wc -l
TCP连接中有多少个连接状态是ESTABLISHED: netstat -ant |grep 80|grep ESTABLISHED|wc -l
TCP连接中有多少个连接状态是CLOSE_WAIT: netstat -ant |grep 80|grep CLOSE_WAIT|wc -l
TCP连接中有多少个连接状态是TIME_WAIT: netstat -ant |grep 80|grep TIME_WAIT|wc -l
使用awk来完成统计信息: netstat -ant |grep 80|awk '{++S[$NF]} END {for (a in S) print a, S[a]}'
- 磁盘IO:
iostat命令可以监控有没有IO非空闲等待,iotop -oP命令可以查看哪个程序正在进行IO。
[patrickxu@vm1 ~]$ iostat
Linux 2.6.32-279.19.3.el6.ucloud.x86_64 (vm1) 06/11/2017 _x86_64_ (8 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.08 0.00 0.06 0.00 0.00 99.86
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
vda 0.45 0.29 8.10 6634946 183036680
vdb 0.12 3.11 30.55 70342034 689955328
说明:
cpu属性值说明:
%user:CPU处在用户模式下的时间百分比。
%nice:CPU处在带NICE值的用户模式下的时间百分比。
%system:CPU处在系统模式下的时间百分比。
%iowait:CPU等待输入输出完成时间的百分比。
%steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。
%idle:CPU空闲时间百分比。
备注:
如果%iowait的值过高,表示硬盘存在I/O瓶颈 如果%idle值高,表示CPU较空闲 如果%idle值高但系统响应慢时,可能是CPU等待分配内存,应加大内存容量。 如果%idle值持续低于10,表明CPU处理能力相对较低,系统中最需要解决的资源是CPU。
cpu属性值说明:
tps:该设备每秒的传输次数
kB_read/s:每秒从设备(drive expressed)读取的数据量;
kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
kB_read: 读取的总数据量;
kB_wrtn:写入的总数量数据量;
查看设备使用率(%util)、响应时间(await)
# 【-d 显示磁盘使用情况,-x 显示详细信息】
# d: detail iostat -d -x -k 1 1
image.png
说明:
rrqm/s: 每秒进行 merge 的读操作数目.即 delta(rmerge)/s
wrqm/s: 每秒进行 merge 的写操作数目.即 delta(wmerge)/s
%util: 一秒中有百分之多少的时间用于 I/O 如果%util接近100%,说明产生的I/O请求太多,I/O系统已经满负荷idle小于70% IO压力就较大了,一般读取速度有较多的wait。