gperftools —— cpu profiler

安装

32 位系统

只要去https://code.google.com/p/gperftools/downloads/list下载gperftools安装就可以了,

./configure

make

make install


64位系统

需要先安装libunwind库 http://gperftools.googlecode.com/svn/trunk/INSTALL 里面说明了原因,如果不安装libunwind库也可以,就是在安装gperftools的时候 enable-frame-pointers, 并且在编译应用程序的时候加上 -fno-omit-frame-pointer

*** NOTE FOR 64-BIT LINUX SYSTEMS

The glibc built-in stack-unwinder on 64-bit systems has some problems
with the perftools libraries.  (In particular, the cpu/heap profiler
may be in the middle of malloc, holding some malloc-related locks when
they invoke the stack unwinder.  The built-in stack unwinder may call
malloc recursively, which may require the thread to acquire a lock it
already holds: deadlock.)

For that reason, if you use a 64-bit system, we strongly recommend you
install libunwind before trying to configure or install gperftools.
libunwind can be found at

   http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-beta.tar.gz

Even if you already have libunwind installed, you should check the
version.  Versions older than this will not work properly; too-new
versions introduce new code that does not work well with perftools
(because libunwind can call malloc, which will lead to deadlock).

There have been reports of crashes with libunwind 0.99 (see
http://code.google.com/p/gperftools/issues/detail?id=374).
Alternately, you can use a more recent libunwind (e.g. 1.0.1) at the
cost of adding a bit of boilerplate to your code.  For details, see
http://groups.google.com/group/google-perftools/msg/2686d9f24ac4365f

   CAUTION: if you install libunwind from the url above, be aware that
   you may have trouble if you try to statically link your binary with
   perftools: that is, if you link with 'gcc -static -lgcc_eh ...'.
   This is because both libunwind and libgcc implement the same C++
   exception handling APIs, but they implement them differently on
   some platforms.  This is not likely to be a problem on ia64, but
   may be on x86-64.

   Also, if you link binaries statically, make sure that you add
   -Wl,--eh-frame-hdr to your linker options. This is required so that
   libunwind can find the information generated by the compiler
   required for stack unwinding.

   Using -static is rare, though, so unless you know this will affect
   you it probably won't.

If you cannot or do not wish to install libunwind, you can still try
to use the built-in stack unwinder.  The built-in stack unwinder
requires that your application, the tcmalloc library, and system
libraries like libc, all be compiled with a frame pointer.  This is
*not* the default for x86-64.

If you are on x86-64 system, know that you have a set of system
libraries with frame-pointers enabled, and compile all your
applications with -fno-omit-frame-pointer, then you can enable the
built-in perftools stack unwinder by passing the
--enable-frame-pointers flag to configure.

Even with the use of libunwind, there are still known problems with
stack unwinding on 64-bit systems, particularly x86-64.  See the
"64-BIT ISSUES" section in README.

If you encounter problems, try compiling perftools with './configure
--enable-frame-pointers'.  Note you will need to compile your
application with frame pointers (via 'gcc -fno-omit-frame-pointer
...') in this case.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++

使用

http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html 将了使用的方法

在代码link过程中添加参数 –lprofiler

1、直接调用提供的api:
这种方式比较适用于对于程序的某个局部来做分析的情况,直接在要做分析的局部调用相关的api即可。
方式:#include <gperftools/profiler.h>, 并调用函数:ProfilerStart() and ProfilerStop() 开始和结束


2、使用环境变量
运行程序:env CPUPROFILE=./helloworld.prof ./helloworld
指定要profile的程序为helloworld,并且指定产生的分析结果文件的路径为./helloworld.prof


如果是多线程,则在线程的开始处调用 ProfilerRegisterThread()

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++

结果分析

我们可以通过pprof生成 text,pdf等各种形式的输出

如 pprof --text ./program prog.prof  > prog.txt

pprof --pdf ./program  prog.prof > prog.pdf

其中 program 是应用程序

如果想生存pdf的格式必须要安装 ghostscript 和 graphviz 两个库


Text mode has lines of output that look like this:

       14   2.1%  17.2%       58   8.7% std::_Rb_tree::find

Here is how to interpret the columns:

  1. Number of profiling samples in this function  分析样本数量(不包含其他函数调用)
  2. Percentage of profiling samples in this function  分析样本百分比(不包含其他函数调用)
  3. Percentage of profiling samples in the functions printed so far  目前为止的分析样本百分比(不包含其他函数调用)
  4. Number of profiling samples in this function and its callees  分析样本数量(包含其他函数调用)
  5. Percentage of profiling samples in this function and its callees  分析样本百分比(包含其他函数调用)
  6. Function name  函数名

含义如下:
14:find函数花费了14个profiling samples
2.1%:find函数花费的profiling samples占总的profiling samples的比例
17.2%:到find函数为止,已经运行的函数占总的profiling samples的比例
58:find函数加上find函数里的被调用者总共花费的profiling samples
8.7%:find函数加上find函数里的被调用者总共花费的profiling samples占总的profiling samples的比例
std::_Rb_tree::find:表示profile的函数
注意: 默认是 100 samples a second,所以得出的结果除以100,得秒单位,即 find函数本身花费了0.14秒, 而包含内部的其他调用之后花费了 0.58秒



关于图形风格输出结果
1.节点
每个节点代表一个函数,节点数据格式:
Class Name
Method Name
local (percentage)
of cumulative (percentage)
  
local时间是函数直接执行的指令所消耗的CPU时间(包括内联函数);性能分析通过抽样方法完成,默认是1秒100个样本,一个样本是10毫秒,即时间单位是10毫秒;
cumulative时间是local时间与其他函数调用的总和;
如果cumulative时间与local时间相同,则不打印cumulative时间项。
2.有向边
调用者指向被调用者,有向边上的时间表示被调用者所消耗的CPU时间

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

注意:

要用google-perftool来分析程序,必须保证程序能正常退出。












要使用 **CPU Profiler** 定位页面卡顿的具体位置,可以按照以下方式进行分析: 1. **启动 CPU Profiler 工具** 在 Android Studio 中打开项目后,选择设备和应用进程,点击顶部菜单栏的 "Profiler" 标签页,进入 CPU Profiler 界面。此界面会显示应用在运行时的 CPU 使用率和线程活动情况[^1]。 2. **记录 CPU 活动数据** 在 CPU Profiler 界面中,点击 "Record" 按钮开始记录方法跟踪记录(Method Tracing),然后执行导致页面卡顿的操作(例如滑动页面或加载内容)。完成操作后,点击 "Stop" 停止记录。系统将展示所记录时间段内各个方法的调用栈和耗时信息[^1]。 3. **查看主线程的方法调用耗时** 在记录的数据中,重点观察主线程(main thread)的调用堆栈。通过展开每个调用栈,可以看到具体方法的执行时间、调用次数以及其子方法的执行情况。如果某个方法的执行时间明显过长,则可能成为页面卡顿的原因。例如,复杂的计算、大量数据处理或频繁的 UI 更新都可能导致主线程阻塞[^1]。 4. **切换视图模式进行详细分析** CPU Profiler 提供了多种视图模式: - **Top Down View**:以树状结构展示从入口函数到子函数的调用关系,并显示每个函数的总执行时间。 - **Bottom Up View**:根据函数被调用的情况排序,显示哪些函数被频繁调用或占用大量 CPU 时间。 - **Flame Chart View**:以火焰图的形式直观地展示函数调用的时间分布,帮助快速识别长时间运行的代码块[^1]。 5. **结合系统跟踪记录分析线程交互** 如果怀疑卡顿与线程调度有关,可以选择启用系统跟踪记录(System Trace)。该功能提供更详细的线程状态变化、CPU 内核瓶颈等信息,帮助分析多个线程之间的资源竞争或锁等待问题。此功能要求设备运行在 Android 7.0(API 级别 24)或更高版本上[^3]。 6. **优化建议与验证** 找到可疑的高耗时方法后,可以在代码中进行优化,例如: - 将复杂计算移到后台线程。 - 减少不必要的重复计算。 - 优化循环逻辑或数据结构的访问效率。 修改完成后,重新运行 CPU Profiler 验证优化效果,确保卡顿问题得到缓解。 ### 示例:检查主线程中的耗时方法 ```java public void loadData() { long startTime = System.currentTimeMillis(); // 模拟一个耗时操作 for (int i = 0; i < 100000; i++) { // 复杂计算 } long endTime = System.currentTimeMillis(); Log.d("Performance", "loadData took " + (endTime - startTime) + "ms"); } ``` 在 CPU Profiler 中,这段代码会在主线程中显示为一个明显的耗时方法,提示需要将其移至后台线程处理以避免影响 UI 流畅性。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值