Systrace的使用总结

目的:

 为了提高apk的性能,使得apk在任何情况下,包括:cpu使用频繁,内存较少,用户重度使用手机(即用户使用一年后的情况,包含大量的图片,音乐和应用数据)都能够快速启动。

 慢启动标准:1000ms。

 一般启动标准:对标友商的启动时间。(一般为100ms)

统计方法:

  1.  monkey测试平台自动统计启动最久的时长和超时次数。
  2.  在event log中,搜索“am_activity_launch_time”找出所有的启动时长,再根据包名进一步筛选。
  3.  在main log中,搜索“Displayed 包名/Activity类”,也可以找出所有的启动记录

其中:测试部使用的是第一种方法。自己排查复现时,只能使用第二种或者第三种方法。

问题复现:

 一般启动分析:

  • 方法1:

  在Android Device Monitor,选中设备,点击Capture System

配置trace,点击OK。然后操作手机,进行启动。

  • 方法2:

 仅限努比亚手机。在onResume延迟1s执行reflectDumpSysTrace()方法,即可在手机内存dump systrace文件。

然后分析执行时间较久的原因。

方法:

 public static void reflectDumpSysTrace(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        try {

            Method method = activityManager.getClass().getDeclaredMethod("dumpSystrace");
            method.setAccessible(true);
            method.invoke(activityManager);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

慢启动分析:

预制步骤:导入重度用户数据,执行整机monkey(50w次)。

方法1:

 在onCreate记录时间,然后在onResume记录时间,比较时间差。大于350ms时,使用上述方法输出systrace。 (onResume会执行多次,应该只计算第一次的执行时间。)

方法2:

  使用设定在local.prop的方式或"adb shell setprop"命令设置以下两个系统属性

"debug.nubia.systrace_launch":activity的启动时间阈值,超过该值则dumpsystrace(单位:ms)

"debug.nubia.systrace_launch_pkg":应用包名(默认为空值),可设置多个,使用":"分隔;也可设置为"*",表示全部应用

工具使用

使用浏览器打开systrace。

操作:

          m:选中当前片段/取消选择

快捷键

问题排查

定位到应用:

  一直下拉,直至找到包名。有时候包名不显示,只能根据pid查找。(无快捷方法)

主要查看UI Thread.

一直到第一帧绘制出来的时间就是启动时间(绿色的F)

启动时间

查找执行时间:用鼠标选择从activity启动开始到第一帧绘制完成的时间片段。

结果如下:

启动耗时详情

总时间7s多,可以看出大部分时间都在休眠。(Running的时间就是cpu执行的时间)

查找休眠长的片段(空白的片段),然后右键查下一个片段(Runable)。查出是那个tid(wake from)阻塞了。然后在右上角查找tid,找出tid是什么。

如果是system service,一般和应用无关。

休眠原因查看:

休眠原因

如果所示:要查找3138(右上角有搜索框)

休眠阻塞原因

结果是一个system service。一般和应用无关,待进一步分析。

详情查看

在debug版本中

adb shell setprop debug.nubia.systrace_more 1

可以打出所有的系统方法。包括是那个方法导致休眠了。

耗时方法详情

可以看出虽然注册广播所需时间只需要.0643ms,但是在系统繁忙的时候,会导致放大上千倍。需要放在异步线程。但是这个广播不是应用控制的

跳帧分析

跳帧:Android中,有UI更新时,16ms会绘制一帧。跳帧就会给用户造成直观的卡顿现象。启动时间计算也是要第一帧显示完成。

定位:红色的F表示绘制失败

分析:

跳帧图

  1. 点击红色的F
  2. 查看警告,站看详情。
  3. 按照时间顺序,逐个分析,比如图中的mesure took 212.60ms就是重点分析对象。
  4. 点击measure方法,定位到具体的方法。
  5. 按“M”选择当前时间段,通过左右移动和放大查看方法详情。
  6. 查看耗时原因。

 

耗时详情分析

名称解释:

  1. Wall Duration    持续时间
  2. CPU Duration     cpu耗时
  3. Self Time            自身方法耗时(不包含其调用方法)
  4. CPU Self Time    自身方法cpu执行时间

案例总结

在该例子中,onMeasue是由于输入法弹窗重新布局触发的。

耗时原因主要是cpu阻塞和嵌套多层导致的。

排查记录:

  • 页面更新UI的大量操作。信息需要异步读取,但是读取完成后,更新UI多,也是耗时的,会导致第一帧无法绘制成功。(采用Idle机制延迟加载)
  • 标题栏延迟加载,只有设置标题的时候才执行onDraw方法。
  • 输入法弹出时重新布局,采用Idle延迟加载
  • 除了更新布局外,其他统一由线程池执行,包括:广播,sp,任何跨进程操作。
  • ActionBar,一般情况下需要耗时18ms。优化后采用自定义view,只需要4ms。
  • 对比新旧数据,相同的数据不更新。
  • 界面嵌套减少,一般要小于三层。
  • 对于需要多个组合与嵌套实现的布局,最好的优化方法就是自定义View,只需要一次绘制。(所有的View都是继承View,结合canvas绘制出来的)
  • 避免使用AppCompatActivity,这个一定会绘制ActionBar,只能隐藏,但是经过了绘制,再隐藏。耗时,无意义

总结

在掌握性能优化方法的同时,也要学习排查性能问题的方法。就是说,掌握了性能方法,并不能完全避免各种各样的性能问题,只有经过测试,排查,才能把性能问题减少到最低。   

   性能优化原则:

  • 最小嵌套
  • 最少组合
  • 尽量异步
  • 重复利用
  • 更新延迟加载
  • 更新局部加载

话外:使用一个“activity+多个Fragment“代替”多个activity” ,可以极大避免慢启动问题。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值