App性能优化——内存、CPU、耗电、启动时间指标获取分析

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 考虑到既然是优化性能,那首先要获取App的相关性能指标,比如: 内存占用、CPU利用率、App启动时间、App耗电量等情况,获取以上各指标后,才能针对性分析确定是否存在优化的可能。

Android App性能优化 (内存、CPU、耗电量、启动时间指标获取)

最近公司要求对App进行性能优化。考虑到既然是优化性能,那首先要获取App的相关性能指标,比如: 内存占用CPU利用率App启动时间App耗电量等情况,获取以上各指标后,才能针对性分析确定是否存在优化的可能。

  • 查看App启动时间(冷启动、热启动)
  • 查看进程内存占用
  • 查看进程CPU使用率
  • 查看App耗电量

一、App启动时间

本小节记录以下三个adb shell 命令:

  • adb shell am start -W [包名]

启动APP,查询App的启动时间

  • adb shell am start -n [包名]/[包名.Activity]

启动一个Activity(不记录启动时间)

  • adb shell am force-stop [包名]

关闭一个APP进程

1.1、App启动时间

查询App的启动时间,可以用以下命令:

// 启动APP,查询App的启动时间
// adb shell am start -W [包名]
adb shell am start -W com.xiaxl.demo

adb shell 查询App启动时间

查询结果中,对应的时间参数详细解析如下:

  • ThisTime:对应activity启动耗时;
  • TotalTime:应用自身启动耗时 = ThisTime + 应用application等资源启动时间
  • WaitTime:系统启动应用耗时 = TotalTime + 系统资源启动时间

1.2、启动一个Activity(不记录启动时间)

单纯启动一个Activity,不记录启动时间,可以使用以下命令。

// 启动一个Activity(不记录启动时间)
// adb shell am start -n [包名]/[包名.Activity]
adb shell am start -n com.xiaxl.demo/com.volley.demo.DmTestActivity

adb shell 启动一个Activity(不记录启动时间)

示例图中,对应Activity在AndroidManifest.xml中的声明方式如下:

<activity
    android:name="com.volley.demo.DmTestActivity"
    android:exported="true"></activity>

1.3、关闭一个App进程

关闭一个App进程用如下命令。

// 关闭一个APP进程用如下命令。
// adb shell am force-stop [包名]
adb shell am force-stop com.xiaxl.demo

adb shell 关闭一个APP进程

二、进程内存占用

本小节记录以下四个adb shell 命令:

  • adb shell dumpsys meminfo [进程名]

Android系统中,查看某一进程的内存占用情况

  • adb shell ps

Android系统中,显示全部系统进程

  • adb shell ps | grep [keyword]

Android系统中,筛选包含特定关键词的进程

  • adb shell cat /proc/meminfo

Android系统中,查看整个系统的内存详情

2.1、查看进程内存占用

Android系统中,查看某一进程的内存占用情况可以使用以下命令。

// 查看Android系统中,某一进程的内存占用情况
// adb shell dumpsys meminfo [进程名]
adb shell dumpsys meminfo com.xiaxl.demo

adb shell查看进程内存占用

以上截图中 TOTAL 字段,为对应进程占用的系统总内存;其他字段不再做详细介绍。

2.2、显示全部系统进程

Android系统中,若不了解对应进程的进程名称,可用如下命令显示全部系统进程

// Android系统中,显示全部系统进程
adb shell ps

adb shell 显示全部系统进程

2.3、筛选进程

Android系统中,亦可根据特定关键词,筛选包含特定关键词的进程

// Android系统中,筛选包含特定关键词的进程
adb shell ps | grep [keyword]

adb shell 筛选包含特定关键词的进程

2.4、查看系统内存详情

Android系统中,如果需要查看整个系统的内存详情,可以使用以下命令。

// Android系统中,查看整个系统的内存详情
adb shell cat /proc/meminfo 

adb shell 查看系统的内存详情

相关参数的详细解释如下所示:

MemTotal:         688576 kB     总内存
MemFree:          153736 kB     空闲内存
MemAvailable:     339884 kB     可用内存
Buffers:              16 kB     给文件的缓冲大小
Cached:           267672 kB     高速缓冲存储器
SwapCached:           36 kB     被高速缓冲存储用的交换空间的大小
Active:           222900 kB     活跃使用中的高速缓冲存储器页面文件大小
Inactive:         123700 kB     不经常使用中的告诉缓冲存储器文件大小
Active(anon):      31800 kB     活跃的匿名内存(进程中堆上分配的内存,是用malloc分配的内存)
Inactive(anon):    57272 kB     不活跃的匿名内存
Active(file):     191100 kB     活跃的file内存
Inactive(file):    66428 kB    不活跃的file内存     
Unevictable:           0 kB    不能被释放的内存页
Mlocked:               0 kB    mlock()系统调用锁定的内存大小
SwapTotal:       2097148 kB    交换空间总大小
SwapFree:        2096884 kB    空闲交换空间
Dirty:                 0 kB    等待被写回到磁盘的大小
Writeback:             0 kB    正在被写回的大小
AnonPages:         78876 kB       未映射页的大小
Mapped:            28556 kB    设备和文件映射大小
Shmem:             10160 kB    已经被分配的共享内存大小
Slab:             102916 kB    内核数据结构缓存大小
SReclaimable:      49616 kB    可收回slab的大小
SUnreclaim:        53300 kB    不可回收的slab的大小
KernelStack:        4416 kB      kernel消耗的内存
PageTables:         6028 kB      管理内存分页的索引表的大小
NFS_Unstable:          0 kB      不稳定页表的大小
Bounce:                0 kB      在低端内存中分配一个临时buffer作为跳转,把位于高端内存的缓存数据复制到此处消耗的内存
WritebackTmp:          0 kB      USE用于临时写回缓冲区的内存
CommitLimit:     2441436 kB      系统实际可分配内存总量
Committed_AS:     308028 kB      当前已分配的内存总量
VmallocTotal:   34359738367 kB   虚拟内存大小
VmallocUsed:      179588 kB    已经被使用的虚拟内存大小
VmallocChunk:   34359310332 kB   malloc 可分配的最大的逻辑连续的内存大小
HardwareCorrupted:     0 kB      删除掉的内存页的总大小(当系统检测到内存的硬件故障时)
AnonHugePages:      6144 kB      匿名 HugePages 数量
CmaTotal:              0 kB    总的连续可用内存
CmaFree:               0 kB      空闲的连续内存
HugePages_Total:       0      预留HugePages的总个数 
HugePages_Free:        0     池中尚未分配的 HugePages 数量
HugePages_Rsvd:        0        表示池中已经被应用程序分配但尚未使用的 HugePages 数量
HugePages_Surp:        0      这个值得意思是当开始配置了20个大页,现在修改配置为16,那么这个参数就会显示为4,一般不修改配置,这个值都是0
Hugepagesize:       2048 kB     每个大页的大小
DirectMap4k:      108416 kB   映射TLB为4kB的内存数量
DirectMap2M:      940032 kB   映射TLB为2M的内存数量
DirectMap1G:           0 kB     映射TLB为1G的内存数量

三、进程CPU占用

本小节记录以下两个adb shell 命令:

  • adb shell dumpsys cpuinfo | grep [进程名]

Android系统中,查看某一进程的CPU占用情况情况

  • adb shell cat /proc/cpuinfo

Android系统中,查看CPU各核心详情

3.1、进程CPU占用

Android系统中,筛选查看某一进程的CPU占用情况可以使用以下命令。

// 查看Android系统中,筛选某一进程的CPU占用情况
adb shell dumpsys cpuinfo | grep [进程名]

// 查看Android系统,CPU占用情况(各进程CPU占用,总的CPU占用)
adb shell dumpsys cpuinfo

adb shell dumpsys cpuinfo | grep [进程名] 命令可以筛选特定进程的CPU占用信息。

adb shell 筛选某一进程的CPU占用

adb shell dumpsys cpuinfo 命令可以展示出每一个进程的CPU占用信息,同时打印总的CPU占用信息。

adb shell 总的CPU占用、各个进程的CPU占用

3.2、CPU各核心详情

Android系统中,如果需要查看CPU各个核心的详细信息,可以使用以下命令。

// Android系统中,查看CPU各个核心的详细信息
adb shell cat /proc/cpuinfo

adb shell 查看CPU各个核心的详细信息

相关参数的详细解释如下所示:

// CPU 架构, 64bit
Processor    : AArch64 Processor rev 14 (aarch64)
// 系统中逻辑处理核的编号,0~7表示8核CPU。
processor    : 0
// 在系统内核启动时粗略测算的CPU速度(Million Instructions Per Second)
BogoMIPS    : 38.40
Features    : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
// ARM 架构
CPU implementer    : 0x51
// 8核
CPU architecture: 8
CPU variant    : 0xd
CPU part    : 0x805
CPU revision    : 14

// 品牌
Hardware    : Qualcomm Technologies, Inc LITO

四、App耗电量

App耗电量相关数据获取 与 分析可以采用以下几种方式:

  • 获取App耗电量数据:adb shell dumpsys batterystats

采用该命令,获取对应包名应用耗电量数据;

  • 分析App电量消耗:Battery-Historian分析工具

采用该分析工具,可以实现对应包名应用耗电量分析;

  • 测试进程电量消耗:perfdog(第三方工具)

https://perfdog.qq.com/article_detail?id=10089&issue_id=0&plat_id=1

4.1、获取App耗电量消耗:dumpsys batterystats

Android系统中,查看对应包名应用电量消耗数据,可以采用如下方式。

a、重置电量数据(连接数据线操作)

首先要重置电量数据(重置电量数据,所有App的电量消耗数据将清零);
然后打开全量日志数据(打开全量电量相关日志记录)。

// 重置电量数据
adb shell dumpsys batterystats --reset
// 打开全量日志记录
adb shell dumpsys batterystats --enable full-wake-history

b、APP相关场景测试(断开数据线)

重置电量数据后,需要拔掉数据线,进行相关APP场景测试

c、导出(重新连接数据线)

重新连接数据线 通过以下命令可在命令行查看对应应用的电量消耗,亦可将电量消耗信息导出到文件中

// 查看 应用电量消耗
adb shell dumpsys batterystats [应用包名] | more
// 导出 应用电量消息,这里使⽤命令more分篇查看电量相关数据
adb shell dumpsys batterystats [应用包名] >1.txt

adb shell 查看应用电量消耗

adb shell dumpsys batterystats导出的电量数据

4.2、分析App电量消耗:Battery-Historian

Battery Historain是谷歌开发的分析工具,其可以用来分析对应包名应用的耗电情况。

因本小节重点还是如何获取对应包名应用耗电相关数据,对于Battery Historain的安装与简单使用可参考我的文章
Mac 中 Battery Historain 安装与使用:
https://xiaxl.blog.csdn.net/article/details/117758299

对应包名应用耗电相关数据获取步骤如下:

a、重置电量数据(连接数据线操作)

首先要重置电量数据(重置电量数据,所有App的电量消耗数据将清零);
然后打开全量日志数据(打开全量电量相关日志记录)。

// 重置电量数据
adb shell dumpsys batterystats --reset
// 打开全量日志记录
adb shell dumpsys batterystats --enable full-wake-history

b、APP相关场景测试(断开数据线)

重置电量数据后,需要拔掉数据线,进行相关APP场景测试

c、导出(重新连接数据线)

重新连接数据线 通过以下命令导出对应应用的电量消耗数据

// Android 7.0(包含) 以上设备执行如下命令:
adb bugreport > bugreport.zip
// Android 6.0(包含) 以下设备执行如下命令:
adb bugreport > bugreport.txt

d、battery-historian 工具分析电量消耗

上一步导出的bugreport文件,上传到battery-historian 工具进行分析。

注:
国内安装Battery Historain太繁琐,主要是各种依赖包国内都下载不下来。
昨天我安装Battery Historain 一下午没搞定,后来搞到半夜一点钟 终于安装完成(中途曾几度想放弃安装,总之安装太繁琐)。
后来发现,已经有人搭建了一个Battery Historain线上环境,相关网址为: https://bathist.ef.lc/

将导出的bugreport文件上传到 https://bathist.ef.lc/ ,便可以开始应用耗电分析了。

battery-historian

4.2、测试进程电量消耗perfdog

PerfDog是腾讯研发的一款性能测试工具,可以测试某一个App对应的某一进程CPU内存电量消耗,具体操作说明:
https://perfdog.qq.com/article_detail?id=10089&issue_id=0&plat_id=1

perfdog
因为这里说的是耗电量测试,我这里举例一小时内,我写的一个测试App后台服务进程耗电量情况如下:

// 我的测试Demo后台进程,一小时耗电量如下:
Sum(Battery)[mWh]:1259.2 (1小时电量消耗)
Avg(Power)[mW]:1259.2
Avg(Voltage)[mV]:3737.7 (1小时平均电压)
Avg(Current)[mA]:337.0 (1小时平均电流)

五、参考:

使用 Battery Historian 分析耗电情况:
https://developer.android.google.cn/topic/performance/power/battery-historian?hl=zh-cn

Battery Historian GitHub地址如下:
https://github.com/google/battery-historian?spm=a2c6h.12873639.0.0.10ed5c987lIJt6

Android 调试桥 (adb)
https://developer.android.google.cn/studio/command-line/adb?hl=zh-cn

android developer dumpsys:
https://developer.android.google.cn/studio/command-line/dumpsys?hl=zh-cn

= THE END =

文章首发于公众号”CODING技术小馆“,如果文章对您有帮助,可关注我的公众号。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
6月前
|
存储 设计模式 监控
快速定位并优化CPU 与 JVM 内存性能瓶颈
本文介绍了 Java 应用常见的 CPU & JVM 内存热点原因及优化思路。
816 166
|
3月前
|
数据采集 数据可视化 数据挖掘
基于Python的App流量大数据分析与可视化方案
基于Python的App流量大数据分析与可视化方案
|
4月前
|
存储 Java
课时4:对象内存分析
接下来对对象实例化操作展开初步分析。在整个课程学习中,对象使用环节往往是最棘手的问题所在。
|
4月前
|
Java 编译器 Go
go的内存逃逸分析
内存逃逸分析是Go编译器在编译期间根据变量的类型和作用域,确定变量分配在堆上还是栈上的过程。如果变量需要分配在堆上,则称作内存逃逸。Go语言有自动内存管理(GC),开发者无需手动释放内存,但编译器需准确分配内存以优化性能。常见的内存逃逸场景包括返回局部变量的指针、使用`interface{}`动态类型、栈空间不足和闭包等。内存逃逸会影响性能,因为操作堆比栈慢,且增加GC压力。合理使用内存逃逸分析工具(如`-gcflags=-m`)有助于编写高效代码。
|
4月前
|
存储 设计模式 监控
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
105 0
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
|
5月前
|
人工智能 运维 监控
2025年阿里云服务器配置选择全攻略:CPU、内存、带宽与系统盘详解
在2025年,阿里云服务器以高性能、灵活扩展和稳定服务助力数字化转型,提供轻量应用服务器、通用型g8i实例等多样化配置,满足个人博客至企业级业务需求。针对不同场景(如计算密集型、内存密集型),推荐相应实例类型与带宽规划,强调成本优化策略,包括包年包月节省成本、ESSD云盘选择及地域部署建议。文中还提及安全设置、监控备份的重要性,并指出未来可关注第九代实例g9i支持的新技术。整体而言,阿里云致力于帮助用户实现性能与成本的最优平衡。 以上简介共计238个字符。
|
6月前
|
Windows
【Azure App Service】对App Service中CPU指标数据中系统占用部分(System CPU)的解释
在Azure App Service中,CPU占比可在App Service Plan级别查看整个实例的资源使用情况。具体应用中仅能查看CPU时间,需通过公式【CPU Time / (CPU核数 * 60)】估算占比。CPU百分比适用于可横向扩展的计划(Basic、Standard、Premium),而CPU时间适用于Free或Shared计划。然而,CPU Percentage包含所有应用及系统占用的CPU,高CPU指标可能由系统而非应用请求引起。详细分析每个进程的CPU占用需抓取Windows Performance Trace数据。
157 40
|
7月前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
663 7
|
7月前
|
开发框架 .NET PHP
网站应用项目如何选择阿里云服务器实例规格+内存+CPU+带宽+操作系统等配置
对于使用阿里云服务器的搭建网站的用户来说,面对众多可选的实例规格和配置选项,我们应该如何做出最佳选择,以最大化业务效益并控制成本,成为大家比较关注的问题,如果实例、内存、CPU、带宽等配置选择不合适,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文将详细解析企业在搭建网站应用项目时选购阿里云服务器应考虑的一些因素,以供参考。
|
8月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
195 1

热门文章

最新文章