性能优化之卡顿分析-计算并优化内存抖动和耗时操作

1 卡顿(卡UI线程)

(1)外部引起的:Activity里面直接进行网络访问/大文件的IO操作。
(2)内存引起的:内存抖动的问题,new Object obj = null;执行耗时方法。
(3)View本身的卡顿:自定义View要注意的,能否优化:

2 优化主方向

(1)避免让主线程执行耗时的操作
(2)优化自定义View卡顿问题

3 解决方法(有问题???)

3.1 步骤一:使用Allocation Tracing来定位大致的情况

参考链接:性能优化之内存泄露(Memory Leak)常用分析工具(另3种)
————>第三部分:3 Allaction Tracking(Android Studio版)

3.2 步骤二:使用TraceView来确定详细的问题所在

3.2.1 TraceView工具能做什么?

  从代码层面分析性能问题,针对每个方法来分析,比如当我们发现我们的应用出现卡顿的时候,我们可以来分析出现卡顿时在方法的调用上有没有很耗时的操作,关注以下两个问题:
  (1)调用次数不多,但是每一次执行都很耗时
  (2)方法耗时不大,但是调用次数太多
  简单一点来说就是:我们能找到频繁被调用的方法,也能找到执行非常耗时的方法,前者可能会造成Cpu频繁调用,手机发烫的问题,后者就是卡顿的问题

3.2.2 参考链接

  Android性能专项测试之TraceView工具(Device Monitor)

3.2.3 TraceView工具启动

(1)打开App操作应用后,start开始追踪,点击stop后停止追踪并且自动打开traceview分析面板:
这里写图片描述
这里写图片描述
(2)打开traceview分析面板:
这里写图片描述
  展开一个方法后可以看到有两部分:Parent表示调用这个方法的方法,可以叫做父方法;Children表示这个方法中调用的其他方法,可以叫做子方法。
Profile面板中各列作用说明:
这里写图片描述

3.2.4 内存抖动分析

(1)图例演示
这里写图片描述
这里写图片描述
(2)找到问题所在:rowAsStr += “, “;

/**
 * com.example.android.mobileperf.compute.MemoryChurnActivity的以下方法:
 *  排序后打印二维数组,一行行打印
 */
public void imPrettySureSortingIsFree() {
   // 优化以前
   int dimension = 300;
   int[][] lotsOfInts = new int[dimension][dimension];
   Random randomGenerator = new Random();
   for(int i = 0; i < lotsOfInts.length; i++) {
       for (int j = 0; j < lotsOfInts[i].length; j++) {
           lotsOfInts[i][j] = randomGenerator.nextInt();
       }
   }

   for(int i = 0; i < lotsOfInts.length; i++) {
       String rowAsStr = "";
       //排序
       int[] sorted = getSorted(lotsOfInts[i]);
       //拼接打印
       for (int j = 0; j < lotsOfInts[i].length; j++) {
           rowAsStr += sorted[j];
           if(j < (lotsOfInts[i].length - 1)){
               rowAsStr += ", ";
           }
       }
   }

   //优化以后
//        StringBuilder sb = new StringBuilder();
//        String rowAsStr = "";
//        for(int i = 0; i < lotsOfInts.length; i++) {
//            //清除上一行
//            sb.delete(0,rowAsStr.length());
//            //排序
//            int[] sorted = getSorted(lotsOfInts[i]);
//            //拼接打印
//            for (int j = 0; j < lotsOfInts[i].length; j++) {
                rowAsStr += sorted[j];
//                sb.append(sorted[j]);
//                if(j < (lotsOfInts[i].length - 1)){
                    rowAsStr += ", ";
//                    sb.append(", ");
//                }
//            }
//            rowAsStr = sb.toString();
//            Log.i("ricky", "Row " + i + ": " + rowAsStr);
//        }
    }
3.2.5 执行耗时方法

(1)图例演示
这里写图片描述
这里写图片描述
(2)找到问题所在:递归问题导致

// com.example.android.mobileperf.compute.CachingActivity
//优化前
public int computeFibonacci(int pInFibSequence) {
   //0 1 1 2 3 5 8
   if (pInFibSequence <= 2) {
       return 1;
   } else {
       return computeFibonacci(pInFibSequence - 1)+ computeFibonacci(pInFibSequence - 2);
   }
}

//优化后的斐波那契数列的非递归算法 caching缓存+批处理思想
public int computeFibonacci(int pInFibSequence) {
    int prev = 0;
    int current = 1;
    int newValue;
    for (int i=1; i<pInFibSequence; i++) {
        newValue = current + prev;
        prev = current;
        current = newValue;
    }
    return current;
}

(3)解决问题思路
  尽量避免让【主线程】执行耗时的操作,让它能快速处理UI事件和Broadcast消息。

4 如何使用Traceview计算某个类的耗时

(1)在onCreate开始和结尾打上trace.

 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Debug.startMethodTracing("textracing");//开始

    sleep();
    login();

     Debug.stopMethodTracing();//结束
}

private void sleep() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

(2)运行程序, 会在手机sdcard或者本地存储上生成一个”textracing.trace”的文件。注意: 需要给程序加上写存储的权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

(3)MAC:通过adb pull将其导出到本地,然后将textracing.trace从手机传到电脑上

adb pull /sdcard/Traceview.trace ~/temp

(4)Windows:直接将textracing.trace从手机传到电脑上(textracing.trace存放在根目录)

(5)Android Studio直接打开
这里写图片描述

5 利用loop()中打印的日志检测应用中的UI卡顿

Android UI性能优化 检测应用中的UI卡顿

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值