寻找性能瓶颈
通常性能瓶颈的表象是资源消耗过多、外部处理系统性能不足或资源消耗不多,但程序的响应速度却仍达不到要求。
资源主要消耗在CPU、文件IO、网络IO及内存方面,机器的资源是有限的,当某资源消耗过多时,通常会造成系统的响应速度变慢。
外部处理的性能不够,主要是所调用的其他系统提供的功能或数据库操作的响应速度不够,所调用的其他系统性能不足,多数情况下也是资源消耗过多,但程序的性能不足造成的。数据库操作性能不足通常可以根据数据库的SQL执行速度、数据库机器的IOPS、数据库的Active Sessions等分析出来。
资源消耗不多,但程序的响应速度仍达不到要求的主要原因是程序代码运行效率不够高、未充分使用资源或程序结构不合理。
对java应用而言,寻找性能瓶颈的方法通常为,首先分析资源的消耗,然后结合java的一些工具来查询程序中造成资源消耗过多的代码。
CPU消耗分析
上下文切换
每个CPU在同一时间只能执行一个线程,Linux采用抢占式调度,即:每个线程分配一定的执行时间,当到达执行时间、线程中有IO阻塞或高优先级线程要执行时,Linux将切换执行的线程,在切换时要存储目前线程的执行状态,并恢复要执行的线程的状态,这个过程,称为上下文切换。
运行队列
每个CPU核都维护了一个可运行的线程队列。
通常,系统的load主要由CPU的运行队列决定,load值越大,就意味着线程会消耗越长的时间才能执行完。
利用率
CPU利用率为CPU在用户进程、内核、终端处理、IO等待以及空闲五个部分使用百分比。这五个值是分析CPU消耗情况的关键指标
对java应用而言,CPU消耗严重主要体现在US、SY两个值上。
US:当us值过高时,表示运行的应用消耗了大部分的CPU。
这时,要找到具体消耗CPU的线程所执行的代码,
Java应用造成us值过高的原因,主要是线程一直处于可运行状态,通常这些线程在执行无阻塞、循环、正则或存储的计算等动作造成的。
另一个可能造成us值过高的原因是:频繁的GC。
SY:当sy值高时,表示Linux花费了更多的时间在进行线程切换。
Java应用造成这种现象的主要原因是启动的线程较多,且这些线程处于不断阻塞和执行状态的变化过程中,这就导致操作系统要不断切换执行的线程,产生大量的上下文切换。
这时,最重要的是找出线程要不断切换状态的原因。