Android性能优化(二)--CPU和内存优化工具及方法

Android性能分析工具及方法(一)

Android性能分析是个老生常谈的话题,其意义不再赘述,下面直奔主题。
接下来是本篇章的重点,常用性能分析工具:
我们常用的有:TraceView、Systrace、系统跟踪(System Tracing)、Android Device Monito(Android Profiler),

一、TraceView

简介

首先声明:

TraceView已弃用!

TraceView已弃用!

TraceView已弃用!

原本的TraceView已经弃用了,现在是结合Android Studio 里面的Android Profiler使用的。AndroidSDK自带的工具,用来分析函数调用过程,可以对Android应用程序及Framwork曾代码进行分析。Android Studio 3.2 或更高版本,应改为使用CPU性能分析器来(见下文)

使用

1.如何使用:代码中插装的方式使用:Debug.startMethodTracting,Debug.stopMethodTracing
class WelcomeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //开始记录针对当前页面的.trace
        val dateFormat: DateFormat = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
        val logDate: String = dateFormat.format(Date())
        Debug.startMethodTracing(this.javaClass.simpleName + "_" + logDate)

        setContentView(R.layout.activity_welcom)
        Handler(Looper.getMainLooper()).postDelayed({
            startActivity(Intent(this, MainActivity::class.java))
            finish()
        }, 500)
        doSthInWelcome1()
        doSthInWelcome2()
    }
    private fun doSthInWelcome1() {
        Thread.sleep(20)
    }
    private fun doSthInWelcome2() {
        Thread.sleep(25)
    }

    override fun onStop() {
        super.onStop()
        //结束记录
        Debug.stopMethodTracing()
    }
}

在startMethodTracing()的入参文件名是可选的,但如果未指定日志名称而再次调用startMethodTracing(),系统会覆盖已保存的日志,如果需要跟踪多个页面或者做比对,建议参考上述代码中修改日志命名方式

2.运行项目,调用目标代码

目标页面或代码执行后,就会生成.trace日志,直至stopMethodTracing

3.打开.trace文件

1 打开AndroidStudio DeviceFile explorer 找到日志文件,右键保存到电脑上

一般情况下系统会将日志文件保存到特定app的私有目录中(getExternalFilesDir() )返回的目录相同:sdcard/Android/data/example_package/files/name.trace

2.然后打开Android Studio的profiler打开本地文件
在这里插入图片描述

打开之后,就可以看到上述途中跟踪的日志

个人使用感受

Debug api 我觉得方便之处在于可以单独统计任意页面,函数,而不会记录大量无关的函数,目标性强,不用费劲寻找目标代码


二、系统跟踪 System Tracing

简介

搭载 Android 9(API 级别 28)或更高版本的设备包含一个名为 System Tracing 的系统级应用。此应用类似于 systrace 命令行实用程序,但允许您直接从测试设备本身录制跟踪记录,而无需插入设备并通过 ADB 连接到该设备。然后,您可以使用此应用与开发团队共享根据这些跟踪记录得出的结果。

在解决应用中与性能相关的 bug(例如启动速度慢、转换速度慢或界面卡顿)时,录制跟踪记录特别有用。

使用:

1.添加系统跟踪的快捷方式
  1. 启用开发者选项(如果尚未启用此选项)。

  2. 打开开发者选项设置屏幕。

  3. 在调试部分中,选择 System Tracing。此时会打开 System Tracing 应用,其中显示了应用菜单。

  4. 在应用菜单中,启用显示“快捷设置”图块,系统会将 System Tracing 图块添加到快捷设置面板中,如图1所示:
    在这里插入图片描述

注意:上述添加快捷方式的步骤是可选的,仍然可以直接在开发者选项中直接使用此功能

2.开始录制
  1. 插装 自定义事件

调用android.os.Trace的api进行记录

class WelcomeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        doSthInWelcome1()
        doSthInWelcome2()
    }

    private fun doSthInWelcome1() {
    	//自定义事件,参数用于标记区分当前事件:例如:WelcomeActivity-doSthInWelcome1
        Trace.beginSection("doSth-1")
        Thread.sleep(20)
        //结束记录
        Trace.endSection()
    }

    private fun doSthInWelcome2() {
    	//自定义事件
        Trace.beginSection("doSth-2")
        Thread.sleep(25)
        //结束记录
        Trace.endSection()
    }
}

注意:

  • Trace.beginSection和endSection必须成对出现,可以嵌套;
  • Trace.beginSection和endSection必须在统一线程中使用。

还有traceAsync可自行研究使用

  1. 录制配置

图 4录制配置

在这里插入图片描述

可以看到,配置中可以配置跟踪的日志类型,录制文件大小等等,具体配置内容自行研究哈

  1. 点按 System Tracing图块,该图块带有“录制跟踪记录”标签。该图块会变为启用状态,并且系统会显示常驻通知,通知您系统正在录制跟踪记录,如图 2、3 所示:

在这里插入图片描述

图 3 启动设备上系统跟踪后出现的常驻通知

在这里插入图片描述

然后运行我们的app或关键页面,然后在通知栏点击通知或者快捷开关手动停止录制

3. 查看跟踪记录

录制结束后,把跟踪记录发送到电脑

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JmYoAXwF-1661830582075)(D:\帖子\启动优化\system-tracing-share1.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N2ZkKJDx-1661830582075)(D:\帖子\启动优化\system-tracing-share2.jpg)]

在搭载 Android 10(API 级别 29)或更高版本的设备上,跟踪文件会使用 .perfetto-trace 文件扩展名保存,并可在 Perfetto 界面中打开。在搭载较旧 Android 版本的设备上,跟踪文件会使用 .trace 文件扩展名(表示 Systrace 格式)保存。

可以使用ADB命令下载:

cd /path-to-traces-on-my-dev-machine
adb pull /data/local/traces/ .

然后使用Perfetto(.trace文件使用Android Profiler)打开该文件:

打开方式:

在这里插入图片描述

打开结果:

在这里插入图片描述

可以看到当前应用的各个线程的各个方法还有我们自定义的事件耗时;

图中具体代表的意义可以查看官方文档

个人使用感受

Trace的api方便之处在于可以自定义函数跟踪,例如某一个插件某个类里面可以方便的根据入参区分,结果预览也很直观。


三、Systrace

Systrace 允许你收集和检查设备上运行的所有进程的计时信息。 它包括Androidkernel的一些数据(例如CPU调度程序,IO和APP Thread),并且会生成HTML报告,方便用户查看分析trace内容。

1.环境配置

Systrace 需要python2.7环境,不支持python3,请自行官网安装python2.7并在安装的时候添加到环境变量;

同时需要确保已经配置android环境变量(将 android-sdk/platform-tools/ 添加到 PATH 环境变量),我已经配置了这个,又添加了systrace的环境变量,但还是提示找不到systrace.py文件,我只能从文件路径下执行了。。。

2.开始执行

python systrace.py -o c:\\users\wilson\desktop\performance.html -t 10

参数解释:

  • -o file 将 HTML 跟踪报告写入指定的 file。如果您未指定此选项,systrace 会将报告保存到 systrace.py 所在的目录中,并将其命名为 trace.html。
  • -t N 跟踪设备活动 N 秒。如果您未指定此选项,systrace 会提示您在命令行中按 Enter 键结束跟踪。

更多参数请见官网命令行

3.结果预览

跟踪结束,会在指定目录生成指定名称.html的跟踪结果,浏览器打开即可看到结果:

在这里插入图片描述

如图,箭头所指点开可以筛选可以看不同进程类型的日志。systrace面板不支持鼠标缩放,快捷键W-放大、S-缩小、A-左移、D-右移

更多使用方法介绍参考官网


四、Android Profiler

1. Profiler是AndroidStudio自带的工具我常用的一个工具,打开方式如下:

在这里插入图片描述

需要注意,这种方式需要app存活才能记录

打开之后可以看到cpu、内存、网络的使用情况

2.查看CPU占用

点击上图中 cpu一栏

在这里插入图片描述

左侧集中记录方式区别:

在这里插入图片描述

选择其中一种开始记录,执行到目标代码之后,点击停止记录后,会自动打开结果如下图:

在这里插入图片描述

  • interaction 用户交互,图中分红圆圈是我在点击按钮;
  • Thread 部分是各个线程的执行情况,可以看到

通过搜索,放大,可以看到我执行的点击事件(主线程sleep 25ms)

在这里插入图片描述

这样就可以看到我们的代码中各个方法的耗时,cpu占用情况,针对性优化

3.查看内存占用

手机运行项目后,链接USB,profiler链接手机和项目,点击主屏幕右侧Memory一栏可以看到:

在这里插入图片描述

左侧record选项:

  • 捕获堆转储(Capture heap dump):查看应用程序中在特定时间点使用内存的对象
  • 记录Native分配(Record native allocations):查看每个C/C++对象在一段时间内是如何分配的
  • 记录java/kotlin分配(Record java/kotlin allocations):查看在一段时间内如何分配每个java/kotlin对象

右侧显示的数据有:

  • java/kotlin层代码分配的对象占用内存
  • Native:C/C++代码分配的对象的内存
  • Graphics:图形缓冲区队列为向屏幕显示像素(包括 GL 表面、GL 纹理等等)所使用的内存
  • Stack:您的应用中的原生堆栈和 Java 堆栈使用的内存。这通常与您的应用运行多少线程有关
  • Code:您的应用用于处理代码和资源(如 dex 字节码、经过优化或编译的 dex 代码、.so 库和字体)的内存
  • Others:您的应用使用的系统不确定如何分类的内存
  • Allocated:您的应用分配的 Java/Kotlin 对象数。此数字没有计入 C 或 C++ 中分配的对象

4.通过捕获堆转储检查内存泄漏

1.我在代码里认为创造一个内存泄漏:

class MainActivity : AppCompatActivity() {
    private val mBinding by lazy { ActivityMainBinding.inflate(LayoutInflater.from(this)) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(mBinding.root)
        mBinding.tvContent.setOnClickListener {
        	//跳转到其它页面并结束当前的页面
            startActivity(Intent(this, ThirdActivity::class.java))
            finish()
        }

        MLeakThread().start()

    }

    //非静态内部类
    inner class MLeakThread : Thread() {
        override fun run() {
            while (true) {
                Log.i(TAG, "onCreate: Thread")
                SystemClock.sleep(20)
            }
        }
    }

}

代码原理是通过一个内部类Thread持有当前Activity.点击事件跳转第三个页面之后结束当前页面

2.开始跟踪堆内存

2.1 运行代码(点击事件跳转)
2.2 左侧record选项选择堆转储方式
2.3 点击面板上部小垃圾筒Force GC 强制回收内存;
2.4 点击Record按钮

然后就可以看到下面的画面:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-glRg56uc-1661830582085)(D:\帖子\启动优化\profiler-capture.jpg)]

点击途中黄色感叹号,Leaks:

在这里插入图片描述

如图所示:

1.点击leaks

2.可以看到mainActivity的实例本该被回收却仍然在,因为我主动写了一个内存泄漏,点击MainActivity

3.然后到-3-所指的地方,可以看到mainActivity的实例,点击它

4.右侧点击Reference选项

5.点击Show nearest GC root only

6.底部Reference就看到发生内存泄漏时候所持有它的代码,点击`jump to source’

7.然后就自动打开了-7-所示的代码,就是我们内存泄露的地方。


以上是CPU 和内存方面优化工具以及方法的简单介绍,下期再讲UI方面的优化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值