性能统计器之利器SamplingProfilerIntegration

来源:《深入理解Android:卷Ⅱ》第3章深入理解SystemServer,本章首先分析了system_server进程的启动过程,然后向读者展示了该进程中所容纳的系统核心服务。本节为SamplingProfilerIntegration分析。

下面来看如何使用SamplingProfilerIntegration进行性能统计。系统中有很多重要进程都需要对性能进行分析,比如Zygote,其相关代码如下:

[-->zygoteInit.java::main]
public static void main(String argv[]) {  
try {  
          //启动性能统计  
          SamplingProfilerIntegration.start();  
          ......//Zygote做自己的工作  
          //结束统计并生成结果文件  
          SamplingProfilerIntegration.writeZygoteSnapshot();  
          ......  
} 

上述代码中的start函数的实现代码如下:

[-->SamplingProfilerIntegration.java::start]
public static void start() {  
      if (!enabled) {//判断是否开启性能统计。读者想一想,enable由谁控制?  
          return;  
      }  
      ......  
      ThreadGroup group = Thread.currentThread().getThreadGroup();  
      SamplingProfiler.ThreadSet threadSet =  
                           SamplingProfiler.newThreadGroupTheadSet(group);  
      //创建一个dalvik的SamplingProfiler,我们暂时不对它进行分析  
      samplingProfiler = new SamplingProfiler(samplingProfilerDepth,  
                                                       threadSet);  
      //启动统计  
      samplingProfiler.start(samplingProfilerMilliseconds);  
      startMillis = System.currentTimeMillis();  
  } 

上边代码中提出了一个问题,即用于判断是否启动性能统计的enable变量由谁控制,答案在该类的static语句中,其实现代码如下:

[-->SamplingProfilerIntegration.java]
static {  
      samplingProfilerMilliseconds = //取系统属性,默认值为0,即禁止性能统计  
                  SystemProperties.getInt("persist.sys.profiler_ms", 0);  
      samplingProfilerDepth =  
                  SystemProperties.getInt("persist.sys.profiler_depth", 4);  
       //如果samplingProfilerMilliseconds的值大于零,则允许性能统计  
      if (samplingProfilerMilliseconds > 0) {  
          File dir = new File(SNAPSHOT_DIR);  
          ......//创建/data/snapshots目录,并使其可写  
          if (dir.isDirectory()) {  
              snapshotWriter = Executors.newSingleThreadExecutor(  
                                                  new ThreadFactory() {  
                      public Thread newThread(Runnable r) {  
                          return new Thread(r, TAG);//创建用于输出统计文件的工作线程  
                      }  
                  });  
              enabled = true;  
           } ......  
      } else {  
          snapshotWriter = null;  
          enabled = false;  
          Log.i(TAG, "Profiling disabled.");  
      }  
 } 

enable的控制竟然放在static语句中,这表明要使用性能统计,就必须重新启动要统计的进程。

启动性能统计后,需要输出统计文件,这项工作由writeZygoteSnapshot函数完成,其实现代码如下:

[-->SamplingProfilerIntegration.java::writeZygoteSnapshot]
public static void writeZygoteSnapshot() {  
      ......  
      //调用writeSnapshotFile函数,注意第一个参数为zygote,用于表示进程名  
      writeSnapshotFile("zygote", null);  
      samplingProfiler.shutdown();//关闭统计  
      samplingProfiler = null;  
      startMillis = 0;  
} 

writeSnapshotFile函数比较简单,功能就是在shots目录下生成一个统计文件,统计文件的名称由两部分组成,合起来就是“进程名_开始性能统计的时刻.snapshot”。另外,writeSnapshotfile内部会调用generateSnapshotHeader函数在该统计文件文件头部写一些特定的信息,例如版本号、编译信息等。

注意 SamplingProfilerIntegration的核心是SamplingProfiler,这个类定义在libcore/dalvik/src/main/java/dalvik/system/profiler/SamplingProfiler.java文件中。感兴趣的读者可以研究一下该类的用法。在实际开发中,笔者一般使用Debug类提供的方法进行性能统计。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值