本人在做手机APP性能数据的过程中,又重新看了一些Android的内存相关知识,对之前写过的一篇APP性能的线程类的方法做了优化,总得来说,就是增加了PSS数据和增加了数据获取之后的数据整理工作。
获取PSS的方法原理是通过adb shell dumpsys命令获取到的,之前放弃了这个方法,因为内存数据太细分了,后来发现细分的更准确。这里没有统计Native Heap和Dalvik Heap,感觉统计数据的话并没有多大的必要。对这块也不是非常了解如果有不对的地方,还请指正。
方法如下:
代码语言:javascript复制 /**
* 获取应用信息 利用Android系统dumpsys命令获取
* 命令能统计到java虚拟的堆内存和栈内存的使用情况
*
* @return 返回内存占用
*/
public int getMemResult() {
String cmd1 = Common.ADB_PATH "adb shell dumpsys meminfo " package_name;
int mem_result = 0;
try {
Process p = Runtime.getRuntime().exec(cmd1);// 通过runtime类执行cmd命令
// 正确输出流
InputStream input = p.getInputStream();// 创建并实例化输入字节流
BufferedReader reader = new BufferedReader(new InputStreamReader(input));// 先通过inputstreamreader进行流转化,在实例化bufferedreader,接收内容
String line = "";
while ((line = reader.readLine()) != null) {// 循环读取
if (line.startsWith(" TOTAL")) {
mem_result = getMemInfo(line);
}
}
reader.close();// 此处reader依赖于input,应先关闭
input.close();
// 错误输出流
InputStream errorInput = p.getErrorStream();// 创建并实例化输入字节流
BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorInput));// 先通过inputstreamreader进行流转化,在实例化bufferedreader,接收内容
String eline = "";
while ((eline = errorReader.readLine()) != null) {// 循环读取
System.out.println(eline);// 输出
}
errorReader.close();// 此处有依赖关系,先关闭errorReader
errorInput.close();
} catch (IOException e) {
output("执行" cmd1 "失败!", e);
}
return mem_result;
}
下面是增加的统计方法,主要是在每次新建进程的时候都会记录一个mark,统计方法写在结束线程的方法里:
代码语言:javascript复制public void stopRecord() {
AppLocalMySql.getInstance().ClearUpPerformaceData(mark);//整理数据
PerformanceThread.key = false;//结束线程
}
代码语言:javascript复制/**
* 整理一次性能数据收集
*
* @param mark
* 统计mark
*/
public void ClearUpPerformaceData(int mark) {
getConnection();
int cpu = 0, pss = 0, rss = 0, vss = 0, total = 0;
String device = null, packages = null, test_name = null;
try {
if (!connection.isClosed()) {
outputSuccess();
Statement statement = connection.createStatement();
String sql = "SELECT AVG(cpu),AVG(pss),AVG(rss),AVG(vss),COUNT(*),device,package,test_name FROM app_result WHERE mark = "
mark;
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
cpu = resultSet.getInt(1);
pss = resultSet.getInt(2);
rss = resultSet.getInt(3);
vss = resultSet.getInt(4);
total = resultSet.getInt(5);
device = resultSet.getString("device");
packages = resultSet.getString("package");
test_name = resultSet.getString("test_name");
}
String sql2 = "INSERT INTO app_report (mark,test_name,package,device,cpu,pss,rss,vss,total) VALUES ("
mark ",'" test_name "','" packages "','" device "'," cpu "," pss ","
rss "," vss "," total ")";
statement.executeUpdate(sql2);
statement.close();
connection.close();
}
} catch (SQLException e) {
output("统计方法出错!", e);
}
}