下面列出一些导致性能问题的常见情况.
- 程序负荷太重, 导致硬件成为性能瓶颈.
- 观察到CPU利用率一直很高, 响应时间岁负荷增加而变长. 当负荷降下来后, 性能又恢复正常. 如果负载的确超过了程序的承受能力, 解决的办法是升级硬件, 或者增加服务器节点, 用负载均衡吧负载分担到多个点上.
- 数据库无法及时返回查询结果, 导致请求无法及时完成.
- 应用服务器上的CPU利用率都正常, 通过检查dump发现工作线程都在等待数据库请求. 解决方法是将监察重点从应用服务器转移到数据库服务器, 并检查数据库请求为何无法及时返回. 可能是数据库很繁忙, 或者数据库发生死锁.
- 由于代码的原因发生死锁.
- 虽然CPU利用率为0, 但是请求总是不返回. 解决办法是通过dump文件检查进程中的各个线程的状态, 找到阻塞的原因.
- 由于代码的原因发生死循环.
区分性能问题的一个重要指标是CPU的利用率.
- 当性能有问题, CPU利用率低的时候, 往往是发生了死锁或在等待一些资源, 比如数据或网络. 解决的思路是检查各个线程在等待什么?
- 当性能有问题, CPU利用率比较高的时候, 要检查负载的情况. 如果负载正常, 那么高CPU往往是由于程序的设计有问题导致的. 解决办法是检查导致CPU繁忙的原因.
总结表格
CPU利用率 \ 负载 | 低 | 正常 | 高 |
低 | 资源争用, 资源被线程长时间占有, 导致所有工作线程都处于等待状态, 导致CPU使用率低. | ||
正常 | 都正常, 只是响应时间总比设计中的响应时间慢一点点, 那么很可能是在某一个细节上的优化不够. 如不代码中频繁地使用正则表达式,而正则表达式的效率又无法达到预期的效果, 整体性能就会下降. 这类问题很难解决, 往往需要通过分析log文件来确定到底哪一个细节比较慢. 一个有效的profiler程序往往能够起到事半功倍的效果. 都正常, 看dump发现工作线程都在等待数据库请求的返回, 那么检查数据库服务器的性能问题, 看是数据库太忙还是有数据库的死锁. | ||
高 | 资源争用, 资源只被短时间拥有. 系统花费大量CPU时间进行线程切换和调度. 导致CPU使用率高, 且波动频繁 | 死循环或轮询. 解决办法是通过dump文件检查高CPU执行的是些什么代码, 是否总在一个循环体中无法结束 | 如果负载下降时, 性能随之恢复正常, 可以说明是负载超越了程序硬件系统的承受能力. 解决方法是升级硬件或添加负载均衡的服务器节点. |
摘自<Windows用户态程序高效排错>
表格属总结类型的原创.