通过top命令,找到消耗cpu的pid
然后可以通过top -p pid查看下
下一步可以输入kill -3 pid >pid.txt 输出堆栈信息到pid.txt(保存的目录为/proc/${pid}/cwd)
也可以根据jstack -l pid|more查看分析
然后再堆栈信息中查找nid(16进制)=最消耗cpu的线程id(十进制)
也可以根据多次打印堆栈定位问题
线程堆栈不能分析的问题
1.线程为什么会跑飞的问题
2.并发bug导致的数据混乱
3.数据库锁表的问题
如果一个系统随着压力的增加,CPU的使用率无法趋近于100%,说明这个系统存在着可优化空间
如果你的CPU没有被充分利用,则有如下可能:
1.施加的压力不足
可能被测试的程序没有被加入足够的的压力(负载),这时候可以通过增加压力,检测系统的响应时间,服务失败率,和CPU的使用率情况。如果增加压力,系统开始出现部分服务失败,系统的响应时间变慢,或者CPU的使用率无法再上升,那么此时的压力应该是系统的饱和压力。即此时的能力是系统当前的最大能力。
2.系统存在瓶颈
a.持续运行缓慢
b.系统性能随时间的增加逐渐下降
c.系统性能随负载的增加逐渐下降
常见的性能瓶颈
1.由于不恰当的同步导致的资源争用
2.sleep的滥用
3.String +的滥用
4.不恰当的线程模型
5.效率低下的SQL语句或者不恰当的数据库设计
6.不恰当的GC参数设置导致的性能低下
7.线程数量不足
8.内存泄漏导致的频繁GC
上面几种瓶颈除了GC导致的性能瓶颈外,其他的都可以通过分析堆栈并解决
性能调优的过程如下图:
一般一个系统一旦出现性能瓶颈,从堆栈上分析,有如下三种最为典型的堆栈特征:
1.绝大多数线程的堆栈都表现为在同一个调用上下文上,且只剩下非常少的空闲线程。可能原因如下:
a.线程的数量过少
b.锁的粒度过大导致的锁竞争
c.资源竞争
d.锁范围内有大量耗时操作,导致锁竞争
e.远程通信的对方处理缓慢(甚至导致socket缓冲区写满),如数据库侧的SQL代码性能低下
2.绝大多数线程处于等待状态
3.线程总的数量很少
注意:一定要在一定的压力下面进行模拟,性能瓶颈才会出现。需要特别注意的是,压力工具的性能一定要高于被测试的应用程序
其他提高性能的方法:如JDK1.7ConcrrentHashMap的实现,使用分段锁
性能调优的终结条件:
1.算法足够优化
2.没有线程/资源的使用不当而导致的CPU利用不足
如果达到上面的条件,无法满足性能要求。只能用钱解决了,没有什么性能问题是不能用钱解决的,如果有,那就是钱不够,哈哈(皮一下)