When doing Android performance monitoring, it would be more intuitive to display the monitored CPU and memory growth changes in graphs. It took a while to implement it in Python. Let’s see how to use Python to draw Android CPU and memory change curves, and generate PNG image of growth curve chart.
What implemented
At first, I wanted to export the collected CPU and memory data to MS spreadsheet to generate a growth curve chart. After doing some research, there is no better way to implement it.
Then, I relized that it is very easy to use Python to draw charts

The specific effect is as follows. The data collected by the CPU and the memory are independent processes.
The memory is divided into three parts
- Total application memory
- Native memory
- Dalvik memory
If there is a memory leak, either in the Native or in the Dalvik, from the graph growth curve It is easy to notice.

Detailed explanation of implementation
Python implementation of CPU chart
# -*- coding: utf-8 -*-
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import json
import sys
import time
import traceback
def startDump():
try:
cpuData = json.loads(sys.argv[1])
imagePath = sys.argv[2]
cpuRateArray = []
timeArray = []
for cpuItem in cpuData:
cpuRateArray.append(float(cpuItem["cpuRate"]))
timeArray.append((float(float(cpuItem["time"]) - float(cpuData[0]["time"]))/1000))
plt.title("Monitor Cpu Rate")
plt.figure(figsize=(10, 8))
plt.plot(timeArray, cpuRateArray, c='red', label='Process CPU')
plt.ylabel("CPURate (%)", fontsize=12)
plt.xlabel("TimeRange:" + formatTime(float(cpuData[0]["time"])) + ' - ' + formatTime(float(cpuData[len(cpuData) -1]["time"])), fontsize=10)
plt.legend()
plt.tight_layout()
plt.savefig(imagePath)
except Exception:
print 'exeption occur:' + traceback.format_exc()
def formatTime(timeMillis):
timeSeconds = float(timeMillis/1000)
timelocal = time.localtime(timeSeconds)
timeFormat = time.strftime("%Y-%m-%d %H:%M:%S", timelocal)
return timeFormat
if __name__ == '__main__':
startDump()
Code language: PHP (php)
Python implementation of memory chart
# -*- coding: utf-8 -*-
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import json
import sys
import time
import traceback
def startDump():
try:
memoryData = json.loads(sys.argv[1])
imagePath = sys.argv[2]
totalPssArray = []
nativePssArray = []
dalvikPssArray = []
timeArray = []
for memoryItem in memoryData:
totalPssArray.append(float(memoryItem["totalPss"])/1024)
nativePssArray.append(float(memoryItem["nativePss"])/1024)
dalvikPssArray.append(float(memoryItem["dalvikPss"])/1024)
timeArray.append((float(float(memoryItem["time"]) - float(memoryData[0]["time"]))/1000))
plt.title("Monitor Memory")
plt.figure(figsize=(10, 8))
plt.plot(timeArray, totalPssArray, c='red', label='Total Memory')
plt.plot(timeArray, nativePssArray, c='yellow', label='Native Memory')
plt.plot(timeArray, dalvikPssArray, c='blue', label='Dalvik Memory')
plt.ylabel("Memory (MB)", fontsize=12)
plt.xlabel("TimeRange:" + formatTime(float(memoryData[0]["time"])) + ' - ' + formatTime(float(memoryData[len(memoryData) -1]["time"])), fontsize=10)
plt.legend()
plt.tight_layout()
plt.savefig(imagePath)
except Exception:
print 'exeption occur:' + traceback.format_exc()
def formatTime(timeMillis):
timeSeconds = float(timeMillis/1000)
timelocal = time.localtime(timeSeconds)
timeFormat = time.strftime("%Y-%m-%d %H:%M:%S", timelocal)
return timeFormat
if __name__ == '__main__':
startDump()
Code language: PHP (php)
data format
There are two parameters passed in by the script, one is the monitored JSON data string value sys.argv[1], and the other is the full path of the saved image file sys.argv[2].
Run the python script:
python dump_chart.py '<JSONString>' cpu_chart.png
Code language: HTML, XML (xml)
Sample data of CPU usage
time is the system timestamp of the device, and the calculation of CPU occupancy can be viewed in the inscription: CPU monitoring of Android performance monitoring.
[
{
"time": "1589435564442.279053",
"cpuRate": "2.17"
},
{
"time": "1589435565655.333008",
"cpuRate": "3.26"
},
{
"time": "1589435566954.137939",
"cpuRate": "2.52"
},
]
Code language: JSON / JSON with Comments (json)
Sampel data of memroy usuage
totalPss, nativePss, and dalvikPss values are the original data extracted from the application memory information output by dumpsys meminfo, corresponding to the Pss Total values of the TOTAL, Native Heap, and Dalvik Heap fields.
[
{
"time": "1589636256923.429932",
"totalPss": 177804,
"nativePss": 27922,
"dalvikPss": 10212
},
{
"time": "1589636258236.298096",
"totalPss": 178021,
"nativePss": 27850,
"dalvikPss": 9990
},
{
"time": "1589636259525.219971",
"totalPss": 177899,
"nativePss": 27742,
"dalvikPss": 9990
}
]
Code language: JSON / JSON with Comments (json)