瓶颈分析

上一篇 / 下一篇  2018-02-23 10:51:54 / 个人分类:性能测试

CMS GC知识

CMS,全称Concurrent Mark and Sweep,用于对年老代进行回收,目标是尽量减少应用的暂停时间,减少full gc发生的机率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代。

一次CMS至少会给Full GC的次数 + 2,因为Full GC的次数是按照老年代GC时stop the world的次数而定的

我们可以认为Major GC == Full GC,他们是一个概念,就是针对老年代/永久代进行GC。

  1. 应用系统负载分析:

服务器负载瓶颈经常表现为,服务器受到的并发压力比较低的情况下,服务器的资源使用率比预期要高,甚至高很多。导致服务器处理能力严重下降,最终有可能导致服务器宕机。实际性能测试工作中,经常会用以下三类资源指标判定是否存在服务器负载瓶颈:

  • CPU使用率
  • 内存使用率
  • Load

一般cup的使用率应低于50%,如果过高有可能程序的算法耗费太多cpu,或者某些代码块进行不合理的占用。Load值尽量保持在cpuS+2 或者cpuS*2,其中cpu和load一般与并发数成正比。

  • 内存可以通过2种方式来查看:

1) 当vmstat命令输出的si和so值显示为非0值,则表示剩余可支配的物理内存已经严重不足,需要通过与磁盘交换内容来保持系统的稳定;由于磁盘处理的速度远远小于内存,此时就会出现严重的性能下降;si和so的值越大,表示性能瓶颈越严重。

2) 用工具监控内存的使用情况,如果出现下图的增长趋势(used曲线呈线性增长),有可能系统内存占满的情况:

%e6%94%af%e4%bb%98%e5%ae%9d%e7%9a%84%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95007

如果出现内存占用一直上升的趋势,有可能系统一直在创建新的线程,旧的线程没有销毁;或者应用申请了堆外内存,一直没有回收导致内存一直增长。

3)内存分页监控sar -B 5 10

输出项说明:
pgpgin/s:表示每秒从磁盘或swap置换到内存的字节数(KB)
pgpgout/s:表示每秒从内存置换到磁盘或SWAP的字节数(KB)
fault/s:每秒钟系统产生的缺页数,即主缺页与次缺页之和。
majflt/s:每秒钟产生的主缺页数。
pgfree/s:每秒被放入空闲队列中的页个数。是已经扫描到了的空闲页,扫描的空闲page越大,代表内存空余越大 
pgscank/s:每秒被kswapd扫描的页个数。
pgscand/s:每秒直接被扫描的页个数。
pgsteal/s:每秒钟从cache中被清除来满足内存需要的页个数。
%vmeff:每秒清除的页(pgsteal)占总扫描页(pgscank+pgscand)的百分比。pgsteal/s 除以( pgscank/s + pgscand/s ),pgsteal/s表示每秒释放的cache((pagecache and swapcache)),这个其实就是cache可以释放的页,当CPU需要的page不在cache中时,需要释放cache中的原来的page,从内存和swap中加载需要的page,pgscank/s表示每秒扫描swap的page , pgscand/s表示每秒扫描内存的page,实际上pgscank/s+pgscand/s就是RAM+SWAP 。当vmeff的值变大时,表示从RAM和Swap中置换到cache的page变多,这就意味着用到swap的机会变多。这个参数用来衡量页面置换效率,  超30% 证明物理内存已经处理不过来。这个值越大,则请求越多,越代表内存有问题。
4.2 Jvm瓶颈分析

对于java应用来说,过高的GC频率也会在很大程度上降低应用的性能。即使采用了并发收集的策略,GC产生的停顿时间积累起来也是不可忽略的,特别是出现cmsgc失败,导致fullgc时的场景。下面举几个例子进行说明:

  1. Cmsgc频率过高,当在一段较短的时间区间内,cmsGC值超出预料的大,那么说明该JAVA应用在处理对象的策略上存在着一些问题,即过多过快地创建了长寿命周期的对象,是需要改进的。或者old区大小分配或者回收比例设置得不合理,导致cms频繁触发,下面看一张gc监控图(蓝色线代表cmsgc)
%e6%94%af%e4%bb%98%e5%ae%9d%e7%9a%84%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95008

由图看出:cmsGC非常频繁,后经分析是因为jvm参数-XX:CMSInitiatingOccupancyFraction设置为15,比例太小导致cms比较频繁,这样可以扩大cmsgc占old区的比例,降低cms频率注。

调优后的图如下:

%e6%94%af%e4%bb%98%e5%ae%9d%e7%9a%84%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95009

  1. fullgc频繁触发

当采用cms并发回收算法,当cmsgc回收失败时会导致fullgc:

%e6%94%af%e4%bb%98%e5%ae%9d%e7%9a%84%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95010

由上图可以看出fullgc的耗时非常长,在6~7s左右,这样会严重影响应用的响应时间。经分析是因为cms比例过大,回收频率较慢导致,调优方式:调小cms的回比例,尽早触发cmsgc,避免触发fullgc。调优后回收情况如下

%e6%94%af%e4%bb%98%e5%ae%9d%e7%9a%84%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95011

可以看出cmsgc时间缩短了很多,优化后可以大大提高。从上面2个例子看出cms比例不是绝对的,需要根据应用的具体情况来看,比如应用创建的对象存活周期长,且对象较大,可以适当提高cms的回收比例。

  1. 疑似内存泄露,先看下图
%e6%94%af%e4%bb%98%e5%ae%9d%e7%9a%84%e6%80%a7%e8%83%bd%e6%b5%8b%e8%af%95012

分析:每次cmsgc没有回收干净,old区呈上升趋势,疑似内存泄露

最终有可能导致OOM,这种情况就需要dump内存进行分析:

  • 找到oom内存dump文件,具体的文件配置在jvm参数里:
  • -XX:HeapDumpPath=/home/admin/logs

-XX:ErrorFile=/home/admin/logs/hs_err_pid%p.log

  • 借助工具:MAT,分析内存最大的对象。

结论

  1. 在单接口压测时,我们用“请求总数/总时长”得到吞吐量;然后再用“吞吐量/平均响应时间”得到实际并发,此举可用来观察系统实际承受的并发;
  2. 在多接口压测时,由于短板效应,同一个流程中的所有接口获得的请求总数和总时长都一样,显然“请求总数/总时长”计算各个子接口的吞吐量不合适,所以改用“并发/平均响应时间”,其中的并发数应在压测工具中埋点统计,不可简单使用工具线程数。

TAG:

 

评分:0

我来说两句

Open Toolbar