gperftools是google出品的一个性能分析工具,相关介绍可见:
https://github.com/gperftools/gperftools/wiki
gperftools性能分析经过抽样方法完成,默认是1秒100个样本,即一个样本是10毫秒,所以程序运行时间要长一些。git
sudo apt-get install automakegithub
从https://github.com/libunwind/libunwind/releases下载最新版本的libunwind源码包
解压到/usr/local/src目录
cd 解压源码目录
./autogen.sh
./configure
make -j6
make installubuntu
从https://github.com/gperftools/gperftools/releases下载最新版本的gperftools源码包
解压到/usr/local/src目录
cd 解压源码目录
./autogen.sh
./configure
make -j6
make installide
sudo apt-get install graphviz函数
这种状况,咱们能够直接在代码中插入性能分析函数。示例代码以下:工具
#include <gperftools/profiler.h> #include <stdlib.h> void f() { int i; for (i=0; i<1024*1024; ++i) { char *p = (char*)malloc(1024*1024*120); free(p); } } int main() { ProfilerStart("test.prof");//开启性能分析 f(); ProfilerStop();//中止性能分析 return 0; }
编译运行,注意编译时须要链接tcmalloc和profiler库。运行后会生成test.prof文件,而后用pprof就能够生成text的分析报告,具体以下:性能
root@ubuntu:/home/zte/test/perf# gcc not_run_alway.c -ltcmalloc -lprofiler root@ubuntu:/home/zte/test/perf# ./a.out PROFILE: interrupts/evictions/bytes = 14/0/776 root@ubuntu:/home/zte/test/perf# pprof --text a.out test.prof Using local file a.out. Using local file test.prof. Total: 14 samples 3 21.4% 21.4% 3 21.4% SpinLock::Unlock (inline) 3 21.4% 42.9% 3 21.4% __GI_madvise 2 14.3% 57.1% 2 14.3% SpinLock::Lock (inline) 1 7.1% 64.3% 1 7.1% TCMalloc_PageMap2::get (inline) 1 7.1% 71.4% 4 28.6% do_malloc_pages 1 7.1% 78.6% 2 14.3% tcmalloc::PageHeap::Delete 1 7.1% 85.7% 2 14.3% tcmalloc::PageHeap::New 1 7.1% 92.9% 4 28.6% tcmalloc::PageHeap::ReleaseAtLeastNPages 1 7.1% 100.0% 1 7.1% tcmalloc::PageHeap::RemoveFromFreeList 0 0.0% 100.0% 2 14.3% SpinLockHolder (inline) 0 0.0% 100.0% 3 21.4% TCMalloc_SystemRelease 0 0.0% 100.0% 14 100.0% __libc_start_main 0 0.0% 100.0% 14 100.0% _start 0 0.0% 100.0% 4 28.6% do_allocate_full (inline) 0 0.0% 100.0% 10 71.4% do_free_pages 0 0.0% 100.0% 4 28.6% do_malloc (inline) 0 0.0% 100.0% 14 100.0% f 0 0.0% 100.0% 14 100.0% main 0 0.0% 100.0% 1 7.1% tcmalloc::PageHeap::Carve 0 0.0% 100.0% 3 21.4% tcmalloc::PageHeap::DecommitSpan 0 0.0% 100.0% 1 7.1% tcmalloc::PageHeap::GetDescriptor (inline) 0 0.0% 100.0% 4 28.6% tcmalloc::PageHeap::IncrementalScavenge 0 0.0% 100.0% 1 7.1% tcmalloc::PageHeap::MergeIntoFreeList 0 0.0% 100.0% 3 21.4% tcmalloc::PageHeap::ReleaseLastNormalSpan 0 0.0% 100.0% 4 28.6% tcmalloc::allocate_full_malloc_oom 0 0.0% 100.0% 3 21.4% ~SpinLockHolder (inline)
输出数据解析:
每行包含6列数据,依次为:
1 分析样本数量(不包含其余函数调用)
2 分析样本百分比(不包含其余函数调用)
3 目前为止的分析样本百分比(不包含其余函数调用)
4 分析样本数量(包含其余函数调用)
5 分析样本百分比(包含其余函数调用)
6 函数名 google
样本数量至关于消耗的CPU时间。
整个函数消耗的CPU时间至关于包括函数内部其余函数调用所消耗的CPU时间 code
运行命令生成函数调用树形式的pdf分析报告:
pprof --pdf a.out test.prof >test.pdf
树上的每一个节点表明一个函数,节点数据格式:
一、函数名 或者 类名+方法名
二、不包含内部函数调用的样本数 (百分比)
三、of 包含内部函数调用的样本数 (百分比) #若是没有内部调用函数则这一项数据不显示orm
一直运行的程序因为不能正常退出,因此不能采用上面的方法。咱们能够用信号量来开启/关闭性能分析,具体代码以下:
#include <gperftools/profiler.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> void gprofStartAndStop(int signum) { static int isStarted = 0; if (signum != SIGUSR1) return; //经过isStarted标记将来控制第一次收到信号量开启性能分析,第二次收到关闭性能分析。 if (!isStarted){ isStarted = 1; ProfilerStart("test.prof"); printf("ProfilerStart success\n"); }else{ ProfilerStop(); printf("ProfilerStop success\n"); } } void f() { int i; for (i=0; i<1024*1024; ++i) { char *p = (char*)malloc(1024*1024); free(p); } } int main() { signal(SIGUSR1, gprofStartAndStop); while(1){ printf("call f\n"); f(); sleep(1);//为了防止死循环,致使信号处理函数得不到调度 } return 0; }
编译运行以下:
root@ubuntu:/home/zte/test/perf# gcc run_always.c -ltcmalloc -lprofiler root@ubuntu:/home/zte/test/perf# ./a.out
经过kill命令发送信号给进程来开启/关闭性能分析:
用top命令查看进程的PID
kill -s SIGUSR1 PID //第一次运行命令启动性能分析
kill -s SIGUSR1 PID //再次运行命令关闭性能分析,产生test.prof
后续分析报告生成同2.1,再也不赘述。