1-简介

  • 如果我们想要测试我们的某些应用在安卓系统上的性能使用情况, 我们可以通过adb桥去查询, 但是如果每次都去手动查询, 自己生成报表,那无疑是非常繁重的工作
  • 而python就是实现性能自动化测试脚本的脚本语言甚至数据分析、可以方便的实现我们的需求
  • 环境依赖: Mac OS、 PyCharm、adb命令1.0.41版本、小米5手机

2-准备

用数据线连接电脑和手机, 并打开手机的开发者usb调试,当在电脑端输入 adb devices
命令能后查看到如下类似输出证明连接成功

[mac@macdeMacBook-Pro ~]$adb devices
List of devices attached
6eafb6ef    device

打开网易云,然后查看网易云后台进程

[mac@macdeMacBook-Pro ~]$adb shell ps | grep music*
u0_a140   13763 763   2220068 318184 futex_wait 0000000000 S com.netease.cloudmusic
u0_a140   13901 763   1955592 148572 SyS_epoll_ 0000000000 S com.netease.cloudmusic:videoplay
u0_a140   13939 763   1945240 152800 SyS_epoll_ 0000000000 S com.netease.cloudmusic:play

主要是对网易云app的两个进程 com.netease.cloudmusic com.netease.cloudmusic:play 进行内存分析,当然也可以选择其他进程

2- ADB 工具类 的 使用

  • 由于要和android设备之间进行交互, 而adb命令就是常用手段之一
  • 那么我们就可以创建子进程去执行本地的adb命令
  • 创建AdbUtil.py文件编写下面代码
import subprocess
import re
def runShellCmd(cmds: str, input=None, catchResult=None) -> str:cmds = "shell " + cmdsreturn runCmd(cmds, input, catchResult)def runCmd(cmds: str, input=None, catchResult=None) -> str:""":param cmds:            adb 命令:param input:           自定义标准输入:param catchResult:     自定义去从标准输出中抓取数据返回的函数:return:                """cmds = 'adb ' + cmds# p = subprocess.Popen(cmds, stdin=subprocess.PIPE, stderr=subprocess.PIPE,#                     creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)sin = subprocess.PIPEif input is not None and type('') != type(input):sin = inputinput = None# stdin、stdout、stderr 分别指定标准输入.标注输出、标准错误输出的位置# 这里设置为管道,就可以用变量接收p = subprocess.Popen(cmds, stdin=sin, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)out_data, err_data = p.communicate(input)# 生成的结果被b''包裹着, 在mac下out_data = str(out_data).strip("b'").strip("'")err_data = str(err_data).strip("b'").strip("'")ret = p.returncode  # 进程执行状态码,0正常if catchResult is None:if out_data != '':return out_dataelse:return err_datacontent = ''if out_data is not None:content += out_dataif err_data is not None and err_data != '':content += err_datamsg = ">>>指令{0},执行过程出现错误: {1}".format(cmds, err_data.strip())print(msg)return catchResult(content)

3-抓取内存信息

核心代码:

  • 为了方便观察,抓20次即可
  • 执行 catch_mem() 方法
def getProcessMem(process_name: str = ""):"""抓取指定进程名称的内存信息:param process_name::return:"""mem_info = AdbUtil.runShellCmd(f"dumpsys meminfo {process_name}").replace(r"\r\n", "\n").replace(r"\n", "\n")# todo 自定义生成的内存信息文件保存目录: process_mem_dir = Constant.MEM_ALLif not os.path.exists(process_mem_dir):os.makedirs(process_mem_dir)# 当前抓取时间now_time = time.strftime('%Y-%m-%d_%H%M%S', time.localtime())# 直接把shell命令结果写入文件即可with open(os.path.join(process_mem_dir, r'mem_' + now_time + r'.txt'), 'w') as f:f.write(mem_info)f.close()del fdef catch_mem() -> NoReturn:count = 20while count:count -= 1print('>>>------------抓取内存数据------------')getProcessMem()  # 抓取总体的内存信息time.sleep(5)print('>>>------------抓取内存数据------------ 完成')

效果最终生成内存信息文件目录如下:

具体内容为:

  • 它代表着这一时刻, 安卓系统每个进程的内存占用情况
  • 接下来主要对 com.netease.cloudmusiccom.netease.cloudmusic:play 两个进程数据的抓取出来
Applications Memory Usage (in Kilobytes):
Uptime: 6668394 Realtime: 189563989Total PSS by process:290,590K: com.netease.cloudmusic (pid 13763 / activities)205,009K: system (pid 1448)120,151K: com.android.systemui (pid 1774 / activities)116,014K: com.miui.home (pid 2713 / activities)86,907K: surfaceflinger (pid 581)81,680K: com.netease.cloudmusic:play (pid 13939)60,001K: com.netease.cloudmusic:videoplay (pid 13901)56,121K: com.android.mms (pid 26214)55,870K: com.android.quicksearchbox (pid 13349)50,151K: com.baidu.input_mi (pid 5107)44,296K: com.kingroot.kinguser:service (pid 13994)42,446K: clatd-rmnet_data6 (pid 28499)38,950K: com.android.phone (pid 1939)35,180K: com.miui.securitycenter.remote (pid 2937)33,103K: com.miui.yellowpage (pid 26158)31,965K: com.android.fileexplorer (pid 17523 / activities)30,751K: com.miui.gallery (pid 16605 / activities)28,547K: tpsd (pid 15014)26,680K: com.miui.whetstone (pid 2629)24,413K: com.miui.analytics (pid 13643)23,982K: com.android.settings (pid 15352 / activities)23,568K: com.miui.cleanmaster:cmsdk (pid 16917)21,652K: android.process.media (pid 13721)21,092K: app_process (pid 9387)20,332K: com.miui.powerkeeper:service (pid 3034)19,673K: com.lbe.security.miui (pid 3310)19,295K: mm-qcamera-daemon (pid 897)18,247K: logd (pid 455)18,142K: kgod (pid 9341)16,511K: com.xiaomi.metoknlp (pid 2864)15,993K: com.miui.daemon (pid 2588)15,938K: com.miui.systemAdSolution (pid 13601)15,522K: com.android.calendar (pid 18319)15,204K: com.xiaomi.xmsf (pid 2503)13,407K: android.process.acore (pid 26129)13,336K: com.xiaomi.finddevice (pid 2609)13,177K: .dataservices (pid 2564)13,000K: com.android.nfc (pid 2603)12,828K: com.miui.cloudservice (pid 17967)12,382K: com.miui.personalassistant (pid 26518)12,229K: com.android.mms (pid 19865)10,614K: zygote (pid 763)10,493K: com.miui.sysbase (pid 2999)10,012K: audioserver (pid 769)9,913K: com.mipay.wallet (pid 26499)9,556K: com.miui.weather2:pushservice (pid 15654)9,307K: com.android.providers.calendar (pid 18339)8,905K: rild (pid 847)8,843K: com.android.settings:remote (pid 15602)8,092K: com.android.deskclock (pid 25934)6,758K: com.miui.contentcatcher (pid 2558)6,668K: com.xiaomi.simactivate.service (pid 26243)6,573K: rild (pid 938)6,115K: zygote64 (pid 761)5,654K: com.miui.core (pid 2749)5,634K: media.extractor (pid 843)5,367K: cameraserver (pid 792)5,314K: ims_rtp_daemon (pid 956)5,262K: cnd (pid 754)4,766K: com.xiaomi.android.dm.service (pid 25404)4,577K: imscmservice (pid 957)4,519K: com.miui.wmsvc (pid 4101)4,519K: mm-pp-dpps (pid 599)4,481K: mtd (pid 906)4,413K: android.ext.services (pid 15250)4,402K: netmgrd (pid 962)4,352K: com.qualcomm.qcrilmsgtunnel (pid 1928)4,202K: com.android.printspooler (pid 14814)4,199K: shelld (pid 764)4,191K: mediaserver (pid 845)4,095K: qseeproxydaemon (pid 896)4,053K: qseer2fdaemon (pid 911)4,041K: qpaydaemon (pid 905)4,015K: qvop-daemon (pid 900)3,814K: com.miui.audioeffect (pid 25836)3,734K: com.qualcomm.qti.services.secureui:sui_service (pid 2645)3,675K: com.qualcomm.timeservice (pid 19888)3,637K: com.xiaomi.micloud.sdk (pid 26995)3,595K: media.codec (pid 802)3,230K: netd (pid 846)2,858K: thermal-engine (pid 755)2,816K: vsimd (pid 907)2,666K: wpa_supplicant (pid 25086)2,516K: imsdatadaemon (pid 921)2,063K: audiod (pid 903)2,043K: usf_proximity (pid 904)2,036K: slim_daemon (pid 1150)1,793K: lowi-server (pid 1149)1,783K: /init (pid 1)1,559K: mcd (pid 2455)1,533K: tcpdump (pid 5096)1,525K: vold (pid 466)1,496K: drmserver (pid 795)1,437K: 260 (pid 7108)1,434K: mediadrmserver (pid 805)1,225K: keystore (pid 799)1,148K: cnss_diag (pid 5095)1,143K: cnss-daemon (pid 889)1,099K: ipacm (pid 928)1,074K: loc_launcher (pid 890)1,052K: qti (pid 951)1,048K: fingerprintd (pid 899)1,046K: sensors.qcom (pid 662)1,023K: time_daemon (pid 902)999K: dpmd (pid 920)995K: imsqmidaemon (pid 757)976K: installd (pid 798)967K: qcom-system-daemon (pid 752)948K: ueventd (pid 423)910K: adbd (pid 10336)902K: pm-service (pid 575)853K: qseecomd (pid 618)829K: gatekeeperd (pid 912)789K: displayfeature (pid 600)747K: perfd (pid 475)746K: seempd (pid 21744)733K: lmkd (pid 579)719K: fdpp (pid 766)719K: mlipayd (pid 908)715K: pm-proxy (pid 598)703K: servicemanager (pid 580)646K: fidoca (pid 909)635K: dumpsys (pid 28666)631K: mqsasd (pid 767)612K: rmt_storage (pid 567)576K: healthd (pid 564)569K: adsprpcd (pid 756)559K: tftp_server (pid 569)551K: otad (pid 765)547K: sh (pid 24482)541K: qseecomd (pid 577)535K: sh (pid 14103)534K: dpmd (pid 850)521K: port-bridge (pid 967)511K: sh (pid 9365)503K: sh (pid 14935)494K: ipacm-diag (pid 917)488K: subsystem_ramdump (pid 6469)480K: hvdcp_opti (pid 759)456K: gpu_monitor (pid 6624)336K: debuggerd64 (pid 465)317K: debuggerd64:signaller (pid 468)309K: debuggerd (pid 464)307K: 61:0 (pid 7101)258K: 61:0 (pid 8197)257K: debuggerd:signaller (pid 469)243K: 41:10139 (pid 14099)243K: 41:10139 (pid 14929)173K: 41:0 (pid 14102)173K: 41:0 (pid 14934)153K: 41:0 (pid 7866)151K: 260 (pid 7115)104K: watchdogd (pid 14504)100K: watchdogd (pid 7584)94K: ku.sud (pid 7576)92K: ktools (pid 14439)67K: ku.sud (pid 7574)Total PSS by OOM adjustment:415,302K: Native86,907K: surfaceflinger (pid 581)42,446K: clatd-rmnet_data6 (pid 28499)28,547K: tpsd (pid 15014)21,092K: app_process (pid 9387)19,295K: mm-qcamera-daemon (pid 897)18,247K: logd (pid 455)18,142K: kgod (pid 9341)10,614K: zygote (pid 763)10,012K: audioserver (pid 769)8,905K: rild (pid 847)6,573K: rild (pid 938)6,115K: zygote64 (pid 761)5,634K: media.extractor (pid 843)5,367K: cameraserver (pid 792)5,314K: ims_rtp_daemon (pid 956)5,262K: cnd (pid 754)4,577K: imscmservice (pid 957)4,519K: mm-pp-dpps (pid 599)4,481K: mtd (pid 906)4,402K: netmgrd (pid 962)4,199K: shelld (pid 764)4,191K: mediaserver (pid 845)4,095K: qseeproxydaemon (pid 896)4,053K: qseer2fdaemon (pid 911)4,041K: qpaydaemon (pid 905)4,015K: qvop-daemon (pid 900)3,595K: media.codec (pid 802)3,230K: netd (pid 846)2,858K: thermal-engine (pid 755)2,816K: vsimd (pid 907)2,666K: wpa_supplicant (pid 25086)2,516K: imsdatadaemon (pid 921)2,063K: audiod (pid 903)2,043K: usf_proximity (pid 904)2,036K: slim_daemon (pid 1150)1,793K: lowi-server (pid 1149)1,783K: /init (pid 1)1,559K: mcd (pid 2455)1,533K: tcpdump (pid 5096)1,525K: vold (pid 466)1,496K: drmserver (pid 795)1,437K: 260 (pid 7108)1,434K: mediadrmserver (pid 805)1,225K: keystore (pid 799)1,148K: cnss_diag (pid 5095)1,143K: cnss-daemon (pid 889)1,099K: ipacm (pid 928)1,074K: loc_launcher (pid 890)1,052K: qti (pid 951)1,048K: fingerprintd (pid 899)1,046K: sensors.qcom (pid 662)1,023K: time_daemon (pid 902)999K: dpmd (pid 920)995K: imsqmidaemon (pid 757)976K: installd (pid 798)967K: qcom-system-daemon (pid 752)948K: ueventd (pid 423)910K: adbd (pid 10336)902K: pm-service (pid 575)853K: qseecomd (pid 618)829K: gatekeeperd (pid 912)789K: displayfeature (pid 600)747K: perfd (pid 475)746K: seempd (pid 21744)733K: lmkd (pid 579)719K: fdpp (pid 766)719K: mlipayd (pid 908)715K: pm-proxy (pid 598)703K: servicemanager (pid 580)646K: fidoca (pid 909)635K: dumpsys (pid 28666)631K: mqsasd (pid 767)612K: rmt_storage (pid 567)576K: healthd (pid 564)569K: adsprpcd (pid 756)559K: tftp_server (pid 569)551K: otad (pid 765)547K: sh (pid 24482)541K: qseecomd (pid 577)535K: sh (pid 14103)534K: dpmd (pid 850)521K: port-bridge (pid 967)511K: sh (pid 9365)503K: sh (pid 14935)494K: ipacm-diag (pid 917)488K: subsystem_ramdump (pid 6469)480K: hvdcp_opti (pid 759)456K: gpu_monitor (pid 6624)336K: debuggerd64 (pid 465)317K: debuggerd64:signaller (pid 468)309K: debuggerd (pid 464)307K: 61:0 (pid 7101)258K: 61:0 (pid 8197)257K: debuggerd:signaller (pid 469)243K: 41:10139 (pid 14099)243K: 41:10139 (pid 14929)173K: 41:0 (pid 14102)173K: 41:0 (pid 14934)153K: 41:0 (pid 7866)151K: 260 (pid 7115)104K: watchdogd (pid 14504)100K: watchdogd (pid 7584)94K: ku.sud (pid 7576)92K: ktools (pid 14439)67K: ku.sud (pid 7574)476,344K: Persistent205,009K: system (pid 1448)120,151K: com.android.systemui (pid 1774 / activities)38,950K: com.android.phone (pid 1939)26,680K: com.miui.whetstone (pid 2629)15,993K: com.miui.daemon (pid 2588)15,204K: com.xiaomi.xmsf (pid 2503)13,336K: com.xiaomi.finddevice (pid 2609)13,177K: .dataservices (pid 2564)13,000K: com.android.nfc (pid 2603)6,758K: com.miui.contentcatcher (pid 2558)4,352K: com.qualcomm.qcrilmsgtunnel (pid 1928)3,734K: com.qualcomm.qti.services.secureui:sui_service (pid 2645)325,770K: Foreground290,590K: com.netease.cloudmusic (pid 13763 / activities)35,180K: com.miui.securitycenter.remote (pid 2937)332,747K: Visible81,680K: com.netease.cloudmusic:play (pid 13939)60,001K: com.netease.cloudmusic:videoplay (pid 13901)50,151K: com.baidu.input_mi (pid 5107)44,296K: com.kingroot.kinguser:service (pid 13994)24,413K: com.miui.analytics (pid 13643)20,332K: com.miui.powerkeeper:service (pid 3034)16,511K: com.xiaomi.metoknlp (pid 2864)15,938K: com.miui.systemAdSolution (pid 13601)10,493K: com.miui.sysbase (pid 2999)4,519K: com.miui.wmsvc (pid 4101)4,413K: android.ext.services (pid 15250)135,687K: Perceptible116,014K: com.miui.home (pid 2713 / activities)19,673K: com.lbe.security.miui (pid 3310)8,843K: A Services8,843K: com.android.settings:remote (pid 15602)41,628K: B Services21,652K: android.process.media (pid 13721)9,556K: com.miui.weather2:pushservice (pid 15654)5,654K: com.miui.core (pid 2749)4,766K: com.xiaomi.android.dm.service (pid 25404)371,036K: Cached56,121K: com.android.mms (pid 26214)55,870K: com.android.quicksearchbox (pid 13349)33,103K: com.miui.yellowpage (pid 26158)31,965K: com.android.fileexplorer (pid 17523 / activities)30,751K: com.miui.gallery (pid 16605 / activities)23,982K: com.android.settings (pid 15352 / activities)23,568K: com.miui.cleanmaster:cmsdk (pid 16917)15,522K: com.android.calendar (pid 18319)13,407K: android.process.acore (pid 26129)12,828K: com.miui.cloudservice (pid 17967)12,382K: com.miui.personalassistant (pid 26518)12,229K: com.android.mms (pid 19865)9,913K: com.mipay.wallet (pid 26499)9,307K: com.android.providers.calendar (pid 18339)8,092K: com.android.deskclock (pid 25934)6,668K: com.xiaomi.simactivate.service (pid 26243)4,202K: com.android.printspooler (pid 14814)3,814K: com.miui.audioeffect (pid 25836)3,675K: com.qualcomm.timeservice (pid 19888)3,637K: com.xiaomi.micloud.sdk (pid 26995)Total PSS by category:472,527K: Dalvik436,483K: Native192,622K: .dex mmap151,645K: .so mmap129,297K: .oat mmap117,536K: EGL mtrack92,916K: GL mtrack91,727K: .art mmap69,264K: Unknown64,578K: Dalvik Other57,817K: .apk mmap57,442K: Gfx dev54,476K: Other mmap32,094K: Stack13,882K: Ashmem2,783K: .ttf mmap2,323K: Other dev125K: .jar mmap0K: Cursor0K: Other mtrackTotal RAM: 3,801,352K (status normal)Free RAM: 2,166,428K (  371,036K cached pss + 1,707,492K cached kernel +    87,900K free)Used RAM: 2,173,785K (1,736,321K used pss +   437,464K kernel)Lost RAM:  -555,544KZRAM:    17,996K physical used for    73,556K in swap (2,306,044K total swap)Tuning: 256 (large 512), oom   322,560K, restore limit   107,520K (high-end-gfx)

3-数据分析

  • 遍历所有内存信息文件,统计出每一时刻网易云的两个进程占用内存的大小, 同时也要合并两个进程在每一时刻进程共同占用的内存大小, 最终用matplotlib画图库的pylab进行绘图, 将数据进行可视化展示

3-1 数据收集

  • 为了方便将抓取出的数据进行存储,定义一个Cache对象 和 DataResult类对抓取的结果进程存储
  • 编写Cache文件, 编写下面代码
from typing import NoReturn# 结果集对象
dataResult = DataResult()# 需要统计的进程列表
ProcessList = ["com.netease.cloudmusic", "com.netease.cloudmusic:play"]class DataResult:""" 其实是一个多级字典,存放每个进程的内存趋势变化结构大致如下: 比如{"com.netease.cloudmusic": {mem: [],     # 绘图所需的 y 坐标集合 (内存大小)x_list:[]      # 绘图所需的 x 坐标集合 (时间)x_start:[]       # 时间基准点(这个里面就存一个时,但是为了统一操作还是定义成集合)},"com.netease.cloudmusic:play": {mem: [],x_list:[]x_start:[]}# 其他进程同上....}"""process_dict: dict = {}def __init__(self) -> None:passdef isContainProcessKey(self, process_name, key) -> bool:process: dict = self.process_dict.get(process_name)if process is None or process.get(key) is None:return Falsevalue_list: list = process.get(key)return len(value_list) != 0def put(self, process_name, key, value) -> NoReturn:if self.process_dict.get(process_name) is None:self.process_dict[process_name] = {}if self.process_dict[process_name].get(key) is None:self.process_dict[process_name][key] = []self.process_dict[process_name][key].append(value)def isContaionProcessValue(self, process_name, key, value) -> bool:"""判断process_dict.process_name.key  是否包含 value:param process_name::param key::param value::return:"""process: dict = self.process_dict.get(process_name)if process is None or process.get(key) is None:return Falseif value in self.process_dict[process_name][key]:return Truereturn Falsedef get(self, process_name, key, default=None) -> list:process: dict = self.process_dict.get(process_name)if process is None or process.get(key) is None:return defaultreturn process[key]def __str__(self) -> str:return str(self.process_dict)

3-2 核心代码:

  • 主方法是 mem_all_trend()
import project.auto_test.entity.Cache as Cache
import project.auto_test.utils.Constant as Constant
import os
import re
import time
from matplotlib import pylab as pl
import numpy as np# 抓取进程内存数据的正则表达式
# 示例:    290,590K: com.netease.cloudmusic (pid 13763 / activities)
mem_info_cp = re.compile(r"\s*([\d,]*)\s*[Kk][Bb]?:\s*(\S*)\s*\(pid\s*\d+(\s*/\s*\S*)?\)")file_name_time_cp = re.compile(r"\d{4}-\d{1,2}-\d{1,2}_\d+")def convertFileName2Time(file_name: str):"""转成时间戳:param file_name::return:"""logTime = file_name_time_cp.search(file_name).group()timeArray = time.strptime(logTime, "%Y-%m-%d_%H%M%S")return time.mktime(timeArray)def computeFormMemAll(file_path):# 过滤掉重复的进程数据,因为内存信息文件里可能存在重复的进程数据visit_set = set()with open(file_path, 'r') as f:# 遍历该内存信息文件的每一行for line in f:ret = mem_info_cp.search(line)if not ret:continue# 获得进程名process_name = ret.group(2)# 获得占用的内存大小mem_size = ret.group(1).replace(",", "")# 如果该进程未被访问过, 并且是在我们要观察的进程范围内,则把结果加入Cache中if process_name not in visit_set and process_name in Cache.ProcessList:visit_set.add(process_name)# 添加纵坐标Cache.dataResult.put(process_name, "mem", float(mem_size) / 1024)# 添加横坐标# 横坐标的时间不直接使用,以第一个内存采集的时间未基准点作时间差if Cache.dataResult.get(process_name, "x_start") is None:Cache.dataResult.put(process_name, "x_start", convertFileName2Time(file_path))Cache.dataResult.put(process_name, "x_list", 0)else:value_lit = Cache.dataResult.get(process_name, "x_start")# 计算时间差del_time = convertFileName2Time(file_path) - value_lit[0]Cache.dataResult.put(process_name, "x_list", del_time)f.close()def mem_all_trend():# todo Constant.MEM_ALL就是上图表示的内存信息文件目录,里面存放每一时刻的内存信息文件mem_all_file_list = os.listdir(Constant.MEM_ALL)mem_all_file_list.sort() # 以防获取的文件列表是乱序的# 1-遍历每一个内存信息文件,将抓取出的结果存放到 Cache的dataResult类中for file_path in mem_all_file_list:# 文件绝对路径file_path = os.path.join(Constant.MEM_ALL, file_path)computeFormMemAll(file_path)# 2- 遍历 Cache的dataResult类的每个进程数据画一条趋势变化图,而且还要合并每个进程的数据再画一条趋势变化图# 2-1 汇总每个进程的数据,合并出横坐标和纵坐标# 横坐标的时间一致不需额外处理, 更复杂的情况是时间不一致这时需要将他们进行混合# 遍历每个横坐标的时间,计算出总的y坐标(内存总大小)process_name_key = Cache.ProcessList[0]all_x_list =  Cache.dataResult.get(process_name_key, "mem")all_y_list = []# 遍历每个 时间x坐标for x in all_x_list:# 去每一个进程找是否存在该x坐标,如果存在合并内存大小y = 0for process_name_key in Cache.dataResult.process_dict:mem_list = Cache.dataResult.get(process_name_key, "mem")x_list = Cache.dataResult.get(process_name_key, "x_list")index = x_list.index(x)if index >= 0:y += mem_list[index]all_y_list.append(y)# 3-绘图line_color = ['b', 'g', 'r', 'c', 'm', 'y', 'k']count = 0title = ""result_dict = Cache.dataResult.process_dict.copy()result_dict["all"] = {}result_dict["all"]["mem"] = all_y_listresult_dict["all"]["x_list"] = all_x_listfor key in result_dict:mem_list = result_dict.get(key).get("mem")x_list = result_dict.get(key).get("x_list")# 计算内存最大值max_mem_value = max(mem_list)# 计算内存平均值avg_mem_value = np.mean(mem_list)if title:if count % 3 == 0 and count != 0:title += '\n'else:title += ' | 'title += '{0}_mean={1:.2f}{3},{0}_max={2:.2f}{3}\n'.format(key, avg_mem_value, max_mem_value, "MB")pl.plot(x_list, mem_list, 'o{0}-'.format(line_color[count]), label=key) count += 1if count >= 7:count = 0pl.title(title)pl.legend(loc='best')pl.xlabel('Time(s)')pl.ylabel('Size({0})'.format("MB"))pl.show(block=False)

执行后生成的结果如下:

打赏

如果觉得文章有用,你可鼓励下作者

Python 动态抓取 Android 进程内存信息 数据可视化相关推荐

  1. python爬取大众点评评论_python爬虫抓取数据 小试Python——爬虫抓取大众点评上的数据 - 电脑常识 - 服务器之家...

    python爬虫抓取数据 小试Python--爬虫抓取大众点评上的数据 发布时间:2017-04-07

  2. php爬取房源,(python) scrapy抓取房天下房源信息

    一.前言 研究房价走势和房源信息. 二.知识准备 1.python相关知识储备 2.对Scrapy框架有基本的了解,知道其运行流程和逻辑 3.Xpath和CSS选择器相关知识(本文只使用Xpath,要 ...

  3. 四、python爬虫抓取购物网站商品信息--图片价格名称

    本篇博客参考:python爬虫入门教程 http://blog.csdn.net/wxg694175346/article/category/1418998 Python爬虫爬取网页图片 http:/ ...

  4. python 爬虫抓取19楼租房信息

    查看19lou.com的Cookie chrome中打开19lou.com,按F12可以打开开发者工具查看 不获取Cookie会导致爬取网站时重定向而抓不到内容 定义headers headers = ...

  5. python自动抓取网管软件的数据_python实现scrapy爬虫每天定时抓取数据的示例代码...

    1. 前言. 1.1. 需求背景. 每天抓取的是同一份商品的数据,用来做趋势分析. 要求每天都需要抓一份,也仅限抓取一份数据. 但是整个爬取数据的过程在时间上并不确定,受本地网络,代理速度,抓取数据量 ...

  6. Python+selenium 抓取美团单页接口数据里的用户评论和用户名称以及打分数据

    一.原理 selenium的原理很简单,就是模拟人对浏览器的操作,人是怎么操作的,在编写代码时就以这个为逻辑来进行编写.编写起来很是简单,并且也能够很容易纠错. 缺点是,速度比较慢,抓取起来耗时,并且 ...

  7. python京东商品采集_利用Python正则表达式抓取京东网商品信息

    京东(JD.com)是中国最大的自营式电商企业,2015年第一季度在中国自营式B2C电商市场的占有率为56.3%.如此庞大的一个电商网站,上面的商品信息是海量的,小编今天就带小伙伴利用正则表达式,并且 ...

  8. Python实现抓取访问特定URL的数据包

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 这篇文章 ...

  9. 小试Python——爬虫抓取大众点评上的数据

    前言 我开通了一个微信公共号"王和阳的航海日志",在上面记录着自己的学习.思考.实践和成长的过程,欢迎关注.交流和拍砖. 碎碎念:某一天一个妹子突然说要让我帮她写个爬虫,貌似在她眼 ...

最新文章

  1. leetcode_486. Predict the Winner
  2. JavaScript实现isPowerOfTwo算法(附完整源码)
  3. MATLAB随机模拟
  4. 经典面试题(20):以下代码将输出的结果是什么?
  5. flutter BottomAppBar 实现不规则底部导航栏
  6. 雪城大学信息安全讲义 3.1 Set-UID 机制如何工作
  7. Python操作docx文档设置居中并创建表格
  8. 程序防止SqlServer使用SqlServer Profiler跟踪
  9. PHP中的e标签和em标签一样吧,html em标签的作用
  10. PowerDesigner中通过VBS脚本修改模型信息(转)
  11. 调色板 palette 详解
  12. uni 获取本地文件_uni-app 图片(文件) 本地存储解决方案
  13. 360wifi使用方法|360wifi使用教程
  14. 弹球打砖块游戏java,Unity 弹球打砖块游戏(简易)
  15. 4244. 【五校联考6day2】yi (Standard IO)
  16. 网贷逾期和信用卡逾期是一样的吗?
  17. java 将doc格式的文档转化为pdf格式(实现Word文件预览)
  18. Elasticsearch:Runtime fields 及其应用(一)
  19. windows下设置GPU加速tensorflow运算(GT940M)
  20. 平均工资发布,IT 业超 13 万元居首;Def Con 黑客大会首次在中国举办

热门文章

  1. matlab人眼虹膜定位,基于Hough变换的人眼虹膜定位方法
  2. 电脑如何创建html文件夹,如何在电脑上创建自己的隐私文件夹
  3. c语言书面作业,华软C语言书面作业14
  4. 解决 linux du: Argument list too long 参数列表过长的办法
  5. excel求和为什么是0_Excel使用小技巧-Excel里的自动求和功能
  6. Acrel-EIOT免调试抄表系统
  7. EXCEL中使用index+match函数进行查找匹配
  8. 警用装备智能库房管理系统设计方案
  9. Ajax和Git-自我总结
  10. 支持加密的开源笔记Joplin