3.6.2 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类提供的方法进行性能统计。