本篇针对应用内存泄漏测试,简单介绍一下内存泄漏的危害,内存泄漏指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。简单来说就是如果存在内存泄漏的话,应用会越用越卡,最后导致应用崩溃。
前提准备条件:
1、手机root权限,模拟器也可
2、对应系统的procrank,procmem,libpagemap.so文件
3、获取内存数据的脚本
4、adb环境
操作步骤:
1、命令行重新挂载一下分区
adb root
adb remount
adb logcat -c
1.1、在ddms中把hprof文件取出来
命令行ddms,选择对应的机器设备,点击下载获取hprof文件
2、将procmem、procrank推到/system/xbin下,将libpagemap.so推到/system/lib下
同时修改三个文件权限
adb push procmem /system/xbin
adb push procrank /system/xbin
adb push libpagemap.so /system/lib
adb shell
cd /system/xbin
chmod 777 procrank
chmod 777 procmem
cd …/lib
chmod 777 libpagemap.so
3、开始输入参考的monkey指令,开始进行随机指令
参考指令
adb shell monkey -p xxx --ignore-timeouts --ignore-crashes --ignore-security-exceptions --monitor-native-crashes --throttle 500 -v -v 36000 > monkey.txt
4、启动脚本,获取procrank数据,等待monkey结束
参考脚本
import os,subprocess,re
def _getDevice():
# 获取所有设备devices,获得一个tuple
deviceRsp = subprocess.Popen("adb devices",stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True).communicate()[0]
# 正则提取一下设备device,return一个list
device = re.findall('(.*)\tdevice',deviceRsp.decode('utf8'))
print(device)
return device
def _getFileName(to_file,device):
# 打开文件,根据设备名称决定,默认用夜神模拟器,端口62001
__device_list = []
for each in device:
str(each).replace(':','_').replace('.','') # 模拟器的坑
if ":" in each:
each = "62001"
# 根据传入的路径判断
if to_file is None:
__device_list.append('{0}/{1}.txt'.format(os.getcwd(),each))
# 删除已有文件
if os.path.exists(__device_list):
os.remove(__device_list)
else:
# 传入路径没有加后缀,给补上
if os.path.splitext(to_file)[1] == '':
__device_list.append(os.path.join(to_file,'{0}.txt'.format(each)))
else:
__device_list.append(to_file)
break
return __device_list
def Procrank(to_file=None,package=None,device='',e_num=1000):
'''
:param to_file:写入文件路径
:param pakage: 包名
:param e_num: 结束循环的次数
:return:
'''
# 检查设备id,如果没有id则获取
try:
if device =='':
device = _getDevice()
elif not isinstance(device,str):
raise TypeError('设备device不正确,请给字串类型')
except:
raise Exception('获取设备错误_getDevice,或输入设备id错误')
# 打开文件
d = _getFileName(to_file,device)
try:
f = open(d[0],'a+',encoding='utf8')
except Exception as e:
raise Exception('错误:%s\t文件打开失败,请确认文件路径,以及文件类型,建议txt文件'%e)
if package is None:
cmd = 'adb shell procrank'
elif os.name == 'posix':
cmd = 'adb shell procrank |grep {0}'.format(package)
elif os.name == 'nt':
cmd = 'adb shell procrank |findstr {0}'.format(package)
# 循环获取procrank
for n in range(e_num):
# windows解码byte类型变成了空,mac解码变成了str,统一用byte
d = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True).stdout.read()
print(str(d))
f.write(str(d))
f.close()
if __name__ == '__main__':
to_file = '1.txt'
Procrank(to_file,package='com.android.gallery3d',device='127.0.0.1:62001',e_num=240000)
5、第二天之后将脚本得到数据复制粘贴到txt文件中,也可以直接观察生成的txt文件。观察执行的应用有无报错
文件内容大致为
b' 2114 1340816K 56312K 12352K 9912K com.android.gallery3d\r\n'
b' 2114 1340816K 56312K 12352K 9912K com.android.gallery3d\r\n'
b' 2114 1340816K 56312K 12352K 9912K com.android.gallery3d\r\n'
b' 2114 1340816K 56312K 12352K 9912K com.android.gallery3d\r\n'
b' 2114 1340816K 56312K 12352K 9912K com.android.gallery3d\r\n'
b' 2114 1340816K 56312K 12352K 9912K com.android.gallery3d\r\n'
b' 2114 1340816K 56312K 12352K 9912K com.android.gallery3d\r\n'
b' 2114 1340816K 56312K 12352K 9912K com.android.gallery3d\r\n'
6、将txt文件中的数据粘贴到excel中,将uss一列所有的数据筛选出来,使用折线图制作
uss为第四列中数据,需要整理这一列数据,去掉k,excel整理这里就不发了。
7、如果发现折线图走势偏上,则再次ddms保存一下hprof文件,发给研发人员或者自己解析一下内存释放问题
补充:
获取包名,前台仅打开要测试的应用,命令行输入:
adb shell dumpsys window w |findstr / |findstr name=