Android Systrace

来源:互联网 发布:西蒙网络面板接线图 编辑:程序博客网 时间:2024/05/21 18:22

Android Systrace

为什么使用Systrace

  • 通过捕获应用以及Android系统进程的执行时间来分析应用的性能
  • 能够捕获一段时间内整个Android系统的运行状态,生成html图
  • 分析Android应用的显示、绘制性能问题

如何抓取Systrace

  1. Android Studio(Tools->Android->Android Device Monitor)
  2. Android SDK中的systrace.py
  3. 直接使用atrace

在代码中添加trace

Java代码中添加

  • 使用beginSection API
    注意,使用此方法只有在应用的debuggable为true,并且在抓取systrace的时候选定该进程才有效。
Trace.beginSection("traceName");registerReceiver(ContextReceiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));Trace.endSection();
  • 反射使用traceBegin API
public class TraceUtil {    private static final String LOG_TAG = TraceUtil.class.getSimpleName();    private static final String TRACE_MARKER_PATH = "/sys/kernel/debug/tracing/trace_marker";    // Using VIEW option, also using others, but APP    private static final long TRACE_TAG_VIEW = 1L << 3;    public static void begin(String methodName) {        Log.i(LOG_TAG, "Trace being...");        try {            Method traceBegin = Trace.class.getDeclaredMethod("traceBegin", long.class, String.class);            traceBegin.invoke(Trace.class, TRACE_TAG_VIEW, methodName);        } catch (Exception e) {            e.printStackTrace();        }    }    public static void end() {        Log.i(LOG_TAG, "Trace end...");        try {            Method traceEnd = Trace.class.getDeclaredMethod("traceEnd", long.class);            traceEnd.invoke(Trace.class, TRACE_TAG_VIEW);        } catch (Exception e) {            e.printStackTrace();        }    }    public static void traceMarkerBegin(String methodName) {        Log.i(LOG_TAG, "traceMarkerBegin");        try {            FileOutputStream fileOutputStream = new FileOutputStream(new File(TRACE_MARKER_PATH));            try {                fileOutputStream.write(("B|" + Process.myPid() + "|" + "wlb").getBytes());                fileOutputStream.flush();            } catch (IOException e) {                e.printStackTrace();            } finally {                // No Need Close            }        } catch (FileNotFoundException e) {            e.printStackTrace();        }    }    public static void traceMarkerEnd() {        Log.i(LOG_TAG, "traceMarkerEnd");        try {            FileOutputStream fileOutputStream = new FileOutputStream(new File(TRACE_MARKER_PATH));            try {                fileOutputStream.write(("E").getBytes());                fileOutputStream.flush();            } catch (IOException e) {                e.printStackTrace();            } finally {                // No Need Close            }        } catch (FileNotFoundException e) {            e.printStackTrace();        }    }}
TraceUtil.begin("wlb");registerReceiver(ContextReceiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));TraceUtil.end();
  • 直接写trace_marker
TraceUtil.traceMarkerBegin("traceName");registerReceiver(ContextReceiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));TraceUtil.traceMarkerEnd();

Native代码中添加

  • 使用NDK提供的API
typedef void (*func_p)(void);static void trace_func(void){    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Test Native Trace");}static void test_native_trace(func_p){    if (ATrace_isEnabled()) {        ATrace_beginSection("traceName");        func_p();        ATrace_endSection();    }}
  • 直接写trace_marker
static inline void begin_trace(int fd){    char buf[MAX_BUFF_SIZE];    int len = snprintf(buf, MAX_BUFF_SIZE, "B|%d|%s", getpid(), "traceName");    if (fd > 0)        write(fd, buf, len);}static inline void end_trace(int fd){    if (fd > 0)        write(fd, "E", 1);}// Note: Not close trace_marker fdstatic void test_trace_marker(func_p){    const char *trace_marker_path = "/sys/kernel/debug/tracing/trace_marker";    int tm_fd = open(trace_marker_path, O_WRONLY);    if (tm_fd < 0) {        return;    }    begin_trace(tm_fd);    func_p();    end_trace(tm_fd);}

traceName

systrace的工作原理

这里写图片描述

使能systrace workflow

这里写图片描述

j3y17qltecmcc:/sys/kernel/debug/tracing # lsREADME                          kprobe_events       traceavailable_events                kprobe_profile      trace_clockavailable_tracers               options             trace_markerbuffer_size_kb                  per_cpu             trace_optionsbuffer_total_size_kb            printk_formats      trace_pipecpu_freq_switch_profile_enabled saved_cmdlines      tracing_cpumaskcurrent_tracer                  saved_cmdlines_size tracing_max_latencyevents                          saved_tgids         tracing_onfree_buffer                     set_event           tracing_threshinstances                       snapshot


  • trace
  • trace_marker
  • buffer_size_kb
  • tracing_on

细节参考/android/kernel/Documentation/trace/下Ftrace文档

应用trace workflow

这里写图片描述