性能分析定位方法

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.png

3、如上图所示,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.png

jvm各主要参数的作用如下:

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。
禁止转载,如需转载请通过简信或评论联系作者。