引言

有时我们需要对程序进行优化、减少程序响应时间。除了一段段地对代码进行时间复杂度分析,我们还有更便捷的方法吗?



若能直接找到影响程序运行时间的函数调用,再有针对地对相关函数进行代码分析和优化,那相比漫无目的地看代码,效率就高多了。



将strace和pstack工具结合起来使用,就可以达到以上目的。strace跟踪程序使用的底层系统调用,可输出系统调用被执行的时间点以及各个调用耗时;pstack工具对指定PID的进程输出函数调用栈。



下面我们通过一个简单的消息收发程序,说明使用strace、pstack进行程序分析的具体方法。



程序说明

该程序是一个简单的socket程序,由server/client组成。server端监听某端口,等待client的连接,client连接server后定时向server发送消息,server每接收一条消息后向client发送响应消息。程序server与client交互如下图示:

在程序运行起来之后,发现server接收到client的submit消息之后,需要较长时间才发出resp响应。通过tcpdump抓包发现,time2与time1的时间间隔在1s左右:

由上初步分析可知,消息响应慢是server端程序问题。下面我们来看如何使用strace和pstack分析server端程序响应慢的原因。

strace查看系统调用

首先我们拉起server/client程序,并使用strace对server进程进行跟踪:

# ps -elf | grep server | grep -v grep
0 S root 16739 22642 0 76 0 - 634 1024 14:26 pts/2 00:00:00 ./server
# strace -o server.strace -Ttt -p 16739
Process 16739 attached - interrupt to quit

稍等一段时间之后,我们将strace停掉, server.strace文件中有以下输出:

14:46:39.741366 select(8, [3 4], NULL, NULL, {1, 0}) = 1 (in [4], left {0, 1648}) <0.998415>
14:46:40.739965 recvfrom(4, "hello", 6, 0, NULL, NULL) = 5 <0.000068>
14:46:40.740241 write(1, "hello\n", 6) = 6 <0.000066>
14:46:40.740414 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 <0.000046>
14:46:40.740565 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000048>
14:46:40.740715 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 <0.000046>
14:46:40.740853 nanosleep({1, 0}, {1, 0}) = 0 <1.000276>
14:46:41.741284 sendto(4, "hello\0", 6, 0, NULL, 0) = 6 <0.000111>

可以看到server接收数据之后(对应recvfrom调用),经过1s左右时间将消息发出(对应sendto调用),从响应时间看,与抓包的结果吻合。又可以看出nanosleep系统调用耗费了1s时间。



因而可以断定响应延时由nanosleep对应的函数调用造成。



那具体是哪一个函数调用呢?在strace输出结果中并不能找到答案,因其输出显示都是系统调用,要显示程序中函数调用栈信息,就轮到pstack上场了。

pstack查看函数堆栈

pstack是一个脚本工具,其核心实现就是使用了gdb以及thread apply all bt命令,下面我们使用pstack查看server进程函数堆栈:

# sh pstack.sh 16739
#0 0x00002ba1f8152650 in __nanosleep_nocancel () from /lib64/libc.so.6
#1 0x00002ba1f8152489 in sleep () from /lib64/libc.so.6
#2 0x00000000004007bb in ha_ha ()
#3 0x0000000000400a53 in main ()

从以上信息可以看出,函数调用关系为:main->ha_ha->sleep,因而我们可以找到ha_ha函数进行分析和优化修改。



小结

本文通过一个server/client程序事例,说明了使用strace和pstack分析响应延时的方法。

由最初server端响应慢现象,到使用strace跟踪出具体耗时的系统调用,再到使用pstack查到程序中具体的耗时函数,一步步找到了影响程序运行时间的程序代码。

更多地了解底层,从操作系统层面着手,更有助于程序性能分析与优化。

转自:http://blog.csdn.net/icechenbing/article/details/7794439

使用strace+pstack利器分析程序性能的更多相关文章

  1. 如何使用strace+pstack利器分析程序性能

    http://www.cnblogs.com/bangerlee/archive/2012/04/30/2476190.html

  2. oradebug/strace/pstack等分析数据库性能问题系列一

    对于性能问题或者一些比较奇怪妖异的问题,有很多点可以着手去分析. 准备写一个系列关于用ash/dba_hist_active_sess_history,用oradebug,用linux命令strace ...

  3. google perftools分析程序性能

    Google perftools 1.功能简介 它的主要功能就是通过采样的方式,给程序中cpu的使用情况进行“画像”,通过它所输出的结果,我们可以对程序中各个函数(得到函数之间的调用关系)耗时情况一目 ...

  4. python cProfile分析程序性能

    转自:http://xianglong.me/article/analysis-python-application-performance-using-cProfile/?utm_source=tu ...

  5. cProfile分析程序性能

    Python标准库中提供了三种用来分析程序性能的模块,分别是cProfile, profile和hotshot,另外还有一个辅助模块stats.这些模块提供了对Python程序的确定性分析功能,同时也 ...

  6. perf + Flame Graph火焰图分析程序性能

    1.perf命令简要介绍 性能调优时,我们通常需要分析查找到程序百分比高的热点代码片段,这便需要使用 perf record 记录单个函数级别的统计信息,并使用 perf report 来显示统计结果 ...

  7. [转]perf + 火焰图分析程序性能

    1.perf命令简要介绍 性能调优时,我们通常需要分析查找到程序百分比高的热点代码片段,这便需要使用 perf record 记录单个函数级别的统计信息,并使用 perf report 来显示统计结果 ...

  8. perf + 火焰图分析程序性能

    1.perf命令简要介绍 性能调优时,我们通常需要分析查找到程序百分比高的热点代码片段,这便需要使用 perf record 记录单个函数级别的统计信息,并使用 perf report 来显示统计结果 ...

  9. 利用vs自带工具分析程序性能

    测试程序写好后可以通过VS2010分析菜单里选择启用性能向导 选择CPU采样后就选择需要分析的项目 测试项目选择完成后就可以运行分析,结束分析后VS2010会提供个详细报告文档 从分析结果来看GetC ...

随机推荐

  1. ASP.NET MVC View向Controller提交数据

    我们知道使用MVC的一个很重的的用途就是把Controller和View之间进行解耦,通过控制器来调用不同的视图,这就注定了Controller和View之间的传值是一个很重的知识点,这篇博文主要解释 ...

  2. tsung: an open-source multi-protocol distributed load testing tool

     ROPERTIES::type: KnowledgeBase_Cloud:END: 开源.多协议.分布式的压力测试工具   Item Summary tsung-recorder start 通过p ...

  3. GitHub这么火,程序员你不学学吗? 超简单入门教程 【转载】

    本GitHub教程旨在能够帮助大家快速入门学习使用GitHub. 本文章由做全栈攻城狮-写代码也要读书,爱全栈,更爱生活.原创.如有转载,请注明出处. GitHub是什么? GitHub首先是个分布式 ...

  4. MySQL数据备份和恢复

    1.数据备份 mysqldump -uroot -p databasename > file.sql 2.数据还原 mysql -u root -p databasename < file ...

  5. sql server两种分页方法

    方法一: --分页方法一 OrderID,CustomerID, EmployeeID,OrderDate,ShippedDate,ShipName,ShipAddress,Freight from ...

  6. ng-init小解

    ng-init可有多个表达式 ng-init= "a= 1;b= 2" 在这里头定义的变量会加入scope作用域 ng-init只能加入不必要的简单逻辑,输入alert() 定义数 ...

  7. Win32 SDK Combo Box

    如下图所示,显示了三种不同风格的Combo Box样式.当然,现在这样看不出第一种与第三种之间的区别,但是第二种与其他两种的区别是明显的,第二种的列表框始终是出于现实状态的. Combo Box: 一 ...

  8. Firebase 相关

    谷歌在 2016年 I/O 大会上推出了 Firebase 的新版本.Firebase 平台提供了为移动端(iOS和Android)和 Web 端创建后端架构的完整解决方案. 从一开始的移动后端即服务 ...

  9. Swift 与 JSON 数据 浅析

    转载自:http://www.cnblogs.com/theswiftworld/p/4660177.html 我们大家平时在开发 App 的时候,相信接触最多的就是 JSON 数据了.只要你的 Ap ...

  10. HDU2181:哈密顿绕行世界问题(DFS)

    哈密顿绕行世界问题 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Sub ...