最近在研究如何获取iOS手机性能数据(主要是内存),看了一圈目前主流的方法主要是两种:1.阿里开源的iOS自动化测试工具tidevice;2.xcode自带的instruments;
文章来源地址https://uudwc.com/A/12bZE
一、移动端性能指标
1.cpu
正常在20%-40%左右,超过80%需要引起重视。
2.内存
rss:私有内存+所有共享内存,pss:私有内存+比例分配共享内存,一般vss>=rss>=pss>=uss;
需要关注退出一个页面后,内存是否有回落;进行某个操作之后,内存是否增长过快。
3.fps
在30-60之间比较合理,低于30会有明显卡顿,高于70感知不到,会浪费图形处理器能力。
4.耗电量
测试前先看规定时间内手机正常待机下(重启后待机)电量消耗为多少。然后再启动待测试APP看看消耗的电量增加了多少取差值。
5.crash
<0.03%表示优秀,<0.1%表示良好。
6.启动时长
7.流量
8.gpu过度渲染
文章来源:https://uudwc.com/A/12bZE
二、tidevice
tidevice是阿里开源的iOS自动化测试工具,能够提供截图、获取手机信息、ipa包的安装和卸载、根据bundleID启动和停止应用、获取指定应用性能数据、模拟xcode运行xctest等功能;taobao-iphone-device/README.md at main · alibaba/taobao-iphone-device · GitHub
安装tidevice
pip3 install -U "tidevice[openssl]"
tidevice可以用命令行或者python脚本方式获取性能数据。
1.命令行方式:
tidevice applist
得到ipa 文件的 bundle id
查看性能数据
tidevice perf -B bundleID
输出数据格式如下, 采集时间使用时间戳格式。
fps {'fps': 46, 'value': 46, 'timestamp': 1655023837471}
gpu {'device': 22, 'renderer': 20, 'tiler': 22, 'value': 22, 'timestamp': 1655023837572}
cpu {'timestamp': 1655023837647, 'pid': 2734, 'value': 0.6984475878545683, 'sys_value': 83.33333333333331, 'count': 2}
memory {'pid': 979, 'timestamp': 1655023837647, 'value': 148.61046600341797}
network {'timestamp': 1655023837613, 'downFlow': 78.1064453125, 'upFlow': 0.7294921875}
2.python脚本方式
import time
import tidevice
from tidevice._perf import DataType
t = tidevice.Device()
# perf = tidevice.Performance(t,[DataType.CPU, DataType.MEMORY, DataType.NETWORK, DataType.FPS, DataType.PAGE, DataType.SCREENSHOT, DataType.GPU])
perf = tidevice.Performance(t,DataType.MEMORY)
def callback(_type:tidevice.DataType,value:dict):
print(_type.value,value)
perf.start('com.meituan.imerchantbiz.ep',callback = callback)
time.sleep(60)
perf.stop()
可以用pyecharts自动生成实时的性能采集报告。
安装pyecharts
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ pyecharts
#绘图
x = [i for i in range(len(d))]
y = d
print(x)
print(y)
#创建对象,可以添加一些参数
line = Line(init_opts=options.InitOpts(width='800px',height='600px'))
#添加x轴y轴数据,注意添加y轴数据的时候必须设置series_name参数,表示图例的名称
line.add_xaxis(xaxis_data=x)
line.add_yaxis(series_name='memory', y_axis=y, is_symbol_show=True, label_opts=options.LabelOpts(is_show=False),
#is_symbol_show=True显示点,label_opts=opts.LabelOpts(is_show=False)不显示值
#设置展示最大值最小值
markpoint_opts=options.MarkPointOpts(
data=[
options.MarkPointItem(type_="max",name="最大值", symbol="pin", symbol_size=[70,50]),
options.MarkPointItem(type_="min", name="最小值",symbol="pin", symbol_size=[70,50], itemstyle_opts={'color':'#3CB371'}),
]
),
#设置展示平均值
markline_opts=options.MarkLineOpts(
data=[options.MarkLineItem(type_="average",name="平均值")]
))
line.render()
os.system('open render.html')
效果示例:可以看到最大值、最小值、平均值;鼠标移动到某一个点,可看到该点数值。
3.遇到的问题
(1)出现报错:tidevice.exceptions.MuxError: ImageMountFailed
解决:可能是由于没有devicesupport,下载对应版本的developer,然后用xcode重新安装wda
(2)出现报错:sh: ./render.html: Permission denied
解决:这是因为没有为程序分配读写权限,chmod 755 render.html
(3)报错:./render.html: line 1: syntax error near unexpected token `newline'
暂未解决,先改成open render.html;
三、xcode-instruments
1.获取内存数据-leaks
xcode-open developer tool-打开instruments;
打开leaks;
选择被测设备和被测应用; 点击启动,项目会跑起来,然后即可观测;
当出现红色的x时,表示有内存泄漏了;
选中红色的x,找到leaks-call tree,在底部找到call tree,选中invert call treee,hede system libraries,然后就会显示类和泄露的方法,双击查看详情就可以开始修改了。
Invert Call Tree 的意思是翻转调用树,意思就是我们在调用函数时,是一层一层的,调用外层函数会一直进入内层,直到最后一层,有点递归的意思,当选中 Invert Call Tree 选项时,会直接显示内层函数,方便我们去寻找。反向输出调用树。把调用层级最深的方法显示在最上面,更容易找到最耗时的操作。
Hide System Libraries :隐藏系统库文件。过滤掉各种系统调用,只显示自己的代码调用。
出现报错:Instruments could not acquire the necessary privileges to profile the target application.