ps -mp pid-o THREAD,tid,time配合pstack pid得到效果可以gdb动态调试程序的部分效果,很多时候还是很方便,命令1可以看到进程的每个线程cpu暂用和停什么调用上
#sudo ps -mp 23723 -o THREAD,tid,time
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME
nobody 93.1 - - - - - - 04:52:18
nobody 0.0 19 - futex_ - - 23723 00:00:00
nobody 0.0 19 - futex_ - - 23724 00:00:00
nobody 0.0 19 - futex_ - - 23725 00:00:00
nobody 6.0 19 - futex_ - - 23726 00:19:01
nobody 6.0 19 - futex_ - - 23727 00:19:05
nobody 6.0 19 - futex_ - - 23728 00:19:06
nobody 6.0 19 - futex_ - - 23729 00:19:07
nobody 6.0 19 - futex_ - - 23730 00:19:05
nobody 6.0 19 - epoll_ - - 23731 00:19:04
nobody 9.5 19 - futex_ - - 23732 00:29:49
nobody 9.4 19 - futex_ - - 23733 00:29:33
nobody 9.4 19 - futex_ - - 23734 00:29:40
nobody 9.4 19 - futex_ - - 23735 00:29:32
然后可以通过以下方式参考调用堆栈
# sudo pstack 23729
Thread 1 (process 23729):
#0 0x0000003b14e0b3dc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1 0x000000000041a545 in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#2 0x000000000047bd0a in runPro(boost::shared_ptr<NetService>) ()
#3 0x000000000047cf81 in boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(boost::shared_ptr<NetService>), boost::_bi::list1<boost::_bi::value<boost::shared_ptr<NetService> > > > >::run() ()
#4 0x000000000051df14 in thread_proxy ()
#5 0x0000003b14e077f1 in start_thread () from /lib64/libpthread.so.0
#6 0x0000003b14ae570d in clone () from /lib64/libc.so.6
这样可以不用想gdb那样暂停程序直接查看调用堆栈了
3.vmstat
一般用法是vmstat 1,表示每隔一秒采样一次
# vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 1270832 812484 3899648 0 0 0 88 2 2 11 9 80 0 0
10 0 0 1256936 812484 3899992 0 0 0 0 16063 21518 32 24 43 0 0
4 0 0 1205956 812484 3900296 0 0 0 868 15078 22397 33 30 34 3 0
4 0 0 1163440 812488 3900728 0 0 0 0 18314 23994 41 34 24 0 0
r:运行队列的进程数,正在等待cpu,运行队列进程数每个核最好不超过3,就是r <= 3 * N_cores
b:处于不可中断睡眠状态的进程数
swpd:虚拟内存使用数,恒为0否则是内存不够用
si/so:从硬盘换入换出内存,最好一直为0否则就是内存不够在使用虚拟内存了即是硬盘,将严重影响性能
bi/bo:读写块设备的块数
in:中断数
cs:上下文交换次数
us:用户空间cpu占用百分比
sy:内核空间和中断cpu占用百分比
id:cpu空闲时间
wa:等待io所花cpu时间
4.iotop是一个用来监视磁盘I/O使用状况的 top 类工具,可监测到哪一个程序使用的磁盘IO的信息
5.iostat工具将对系统的磁盘操作活动进行监视
6.dstat可以统计cpu、硬盘读写、换页等,不过我用来看流量到是很方便,man dstat很多有时间再研究
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
11 5 80 0 2 2|1048B 344k| 0 0 | 0 0 |1245 8829
32 15 35 4 6 9| 0 3368k| 25M 19M| 0 0 | 17k 23k
41 15 30 0 5 9| 0 0 | 30M 19M| 0 0 | 17k 22k
33 14 41 0 4 8| 0 0 | 19M 19M| 0 0 | 17k 23k
38 16 29 0 5 12| 0 0 | 40M 19M| 0 0 | 18k 24k
7.strace/ltrace
8.mpstat -P ALL 1每隔一秒显示所有cpu的使用情况
9.time
time ./program
输出:
real 2m30.295s
user 0m0.000s
sys 0m0.004s
9.gprof
gprof 可以为 Linux平台上的程序精确分析性能瓶颈。gprof精确地给出函数被调用的时间和次数,给出函数调用关系。
只需要编译的时候加-pg选项,在程序运行目录会生成gmon.out,一般用法: gprof –b 二进制程序 gmon.out >report.txt
grpof使用很方便,但是prof只能处理单线程,网上有人重写了pthread_create也可以支持多线,不过没试过
10.perf
1.gcc – o t1 – g test.c
2.perf stat ./t1
3.perf record – e cpu-clock ./t1 4.perf report 现在就可以查看cpu占用较高的函数调用了
11. oprofile需要重新编译内核,为尝试
12.gperftools
这是google的一套性能测试工具使用到时挺方便
1.CPUPROFILE=./a.prof ./a.out
2.pprof --text ./a.out ./a.prof
13.systemtap
SystemTap 是监控和跟踪运行中的Linux 内核的操作的动态方法,需要自己写脚本,还没时间深入研究功效
注意systemtap有个latencytop脚本感觉非常有用,可以追踪各种系统延迟,比如什么原因导致上下午切换等,由于我的系统没有打开CONFIG_LATENCYTOP选项,所以也没测试过
13.valgrind
valgrind处理内存泄露非常有用
以上罗列的工具非常多,都没有深入的研究,很多看到不知道的系统调用也不知道如何是好了,功力还是太浅,待完善
浙公网安备 33010602011771号