Emmagee学习之获取内存及CPU占用等数据
kybv7973
8年前
<p>Emmagee 是网易杭州研究院QA团队开发的一个简单易上手的Android性能监测小工具,主要用于监控单个App的CPU,内存,流量,启动耗时,电量,电流等性能状态的变化,且用户可自定义配置监控的频率以及性能的实时显示,并最终生成一份性能统计文件。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/2032017491f08ef2642dae68407c575e.png"></p> <p style="text-align:center">这里写图片描述</p> <p>测试QQ的效果如下:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/8387d2ce3e31d4438f6bf97ee59e2735.jpg"></p> <p style="text-align:center">这里写图片描述</p> <pre> <code class="language-java">/** * 通过pid获取应用占用的内存 * @return */ public int getPidMemorySize(int pid, Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); int[] myMempid = new int[] { pid }; Debug.MemoryInfo[] memoryInfo = am.getProcessMemoryInfo(myMempid); memoryInfo[0].getTotalSharedDirty(); int memSize = memoryInfo[0].getTotalPss(); return memSize; }</code></pre> <pre> <code class="language-java">/** * 获取设备可用内存 */ public long getFreeMemorySize(Context context) { ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo(); ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); am.getMemoryInfo(outInfo); long avaliMem = outInfo.availMem; return avaliMem / 1024; }</code></pre> <pre> <code class="language-java">/** * 获取设备总内存 */ public long getTotalMemory() { String memInfoPath = "/proc/meminfo"; String readTemp = ""; String memTotal = ""; long memory = 0; try { FileReader fr = new FileReader(memInfoPath); BufferedReader localBufferedReader = new BufferedReader(fr, 8192); while ((readTemp = localBufferedReader.readLine()) != null) { if (readTemp.contains("MemTotal")) { String[] total = readTemp.split(":"); memTotal = total[1].trim(); } } localBufferedReader.close(); String[] memKb = memTotal.split(" "); memTotal = memKb[0].trim(); Log.d(LOG_TAG, "memTotal: " + memTotal); memory = Long.parseLong(memTotal); } catch (IOException e) { Log.e(LOG_TAG, "IOException: " + e.getMessage()); } return memory; }</code></pre> <pre> <code class="language-java">/** * 获取dalvik与native分别占用的内存,仅root可用 */ public static String[][] parseMeminfo(int pid) { boolean infoStart = false; // [][],00:native heap size,01:native heap alloc;10: dalvik heap // size,11: dalvik heap alloc String[][] heapData = new String[2][2]; try { Runtime runtime = Runtime.getRuntime(); process = runtime.exec("su"); DataOutputStream os = new DataOutputStream(process.getOutputStream()); os.writeBytes("dumpsys meminfo " + pid + "\n"); os.writeBytes("exit\n"); os.flush(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = bufferedReader.readLine()) != null) { line = line.trim(); if (line.contains("Permission Denial")) { break; } else { // 当读取到MEMINFO in pid 这一行时,下一行就是需要获取的数据 if (line.contains("MEMINFO in pid")) { infoStart = true; } else if (infoStart) { String[] lineItems = line.split("\\s+"); int length = lineItems.length; if (line.startsWith("size")) { heapData[0][0] = lineItems[1]; heapData[1][0] = lineItems[2]; } else if (line.startsWith("allocated")) { heapData[0][1] = lineItems[1]; heapData[1][1] = lineItems[2]; break; } else if (line.startsWith("Native")) { Log.d(LOG_TAG, "Native"); Log.d(LOG_TAG, "lineItems[4]=" + lineItems[4]); Log.d(LOG_TAG, "lineItems[5]=" + lineItems[5]); heapData[0][0] = lineItems[length-3]; heapData[0][1] = lineItems[length-2]; } else if (line.startsWith("Dalvik")) { Log.d(LOG_TAG, "Dalvik"); Log.d(LOG_TAG, "lineItems[4]=" + lineItems[4]); Log.d(LOG_TAG, "lineItems[5]=" + lineItems[5]); heapData[1][0] = lineItems[length-3]; heapData[1][1] = lineItems[length-2]; break; } } } } } catch (IOException e) { e.printStackTrace(); } return heapData; }</code></pre> <pre> <code class="language-java">/** * 获取cpu个数,即处理器核心数 * @return */ public int getCpuNum() { try { // Get directory containing CPU info File dir = new File("/sys/devices/system/cpu/"); // Filter to only list the devices we care about File[] files = dir.listFiles(new CpuFilter()); return files.length; } catch (Exception e) { e.printStackTrace(); return 1; } }</code></pre> <pre> <code class="language-java">/** * 获取cpu列表 */ public ArrayList<String> getCpuList() { ArrayList<String> cpuList = new ArrayList<String>(); try { // Get directory containing CPU info File dir = new File("/sys/devices/system/cpu/"); // Filter to only list the devices we care about File[] files = dir.listFiles(new CpuFilter()); for (int i = 0; i < files.length; i++) { cpuList.add(files[i].getName()); } return cpuList; } catch (Exception e) { e.printStackTrace(); cpuList.add("cpu0"); return cpuList; } }</code></pre> <pre> <code class="language-java">public String getCpuName() { try { RandomAccessFile cpuStat = new RandomAccessFile("/proc/cpuinfo", "r"); // check cpu type String line; while (null != (line = cpuStat.readLine())) { String[] values = line.split(":"); if (values[0].contains("model name") || values[0].contains("Processor")) { cpuStat.close(); Log.d(LOG_TAG, "CPU name="+values[1]); return values[1]; } } } catch (IOException e) { Log.e(LOG_TAG, "IOException: " + e.getMessage()); } return ""; }</code></pre> <pre> <code class="language-java">/** * 获取网络流量,上传和下载的总和 */ public long getTrafficInfo() { Log.i(LOG_TAG, "get traffic information"); long rcvTraffic = -1; long sndTraffic = -1; // Use getUidRxBytes and getUidTxBytes to get network traffic,these API // return both tcp and udp usage rcvTraffic = TrafficStats.getUidRxBytes(Integer.parseInt(uid)); sndTraffic = TrafficStats.getUidTxBytes(Integer.parseInt(uid)); if (rcvTraffic == -1 || sndTraffic == -1) { return -1; } else return rcvTraffic + sndTraffic; }</code></pre> <p>cpu使用率的计算稍微有些不同:</p> <pre> <code class="language-java">// 先获取当前pid的占用情况 String processPid = Integer.toString(pid); String cpuStatPath = "/proc/" + processPid + "/stat"; try { // monitor cpu stat of certain process RandomAccessFile processCpuInfo = new RandomAccessFile(cpuStatPath, "r"); String line = ""; StringBuffer stringBuffer = new StringBuffer(); stringBuffer.setLength(0); while ((line = processCpuInfo.readLine()) != null) { stringBuffer.append(line + "\n"); } String[] tok = stringBuffer.toString().split(" "); processCpu = Long.parseLong(tok[13]) + Long.parseLong(tok[14]); processCpuInfo.close(); } catch (FileNotFoundException e) { Log.w(LOG_TAG, "FileNotFoundException: " + e.getMessage()); } catch (IOException e) { e.printStackTrace(); }</code></pre> <pre> <code class="language-java">// 再获取总的cpu使用情况 try { // monitor total and idle cpu stat of certain process RandomAccessFile cpuInfo = new RandomAccessFile(CPU_STAT, "r"); String line = ""; while ((null != (line = cpuInfo.readLine())) && line.startsWith("cpu")) { String[] toks = line.split("\\s+"); idleCpu.add(Long.parseLong(toks[4])); totalCpu.add(Long.parseLong(toks[1]) + Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4]) + Long.parseLong(toks[6]) + Long.parseLong(toks[5]) + Long.parseLong(toks[7])); } cpuInfo.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }</code></pre> <p>当前进行所占CPU的算法是:100*(processCpuTimeS-processCpuTimeF) / (totalCpuTimeS-totalCpuTimeF)</p> <p>CPU总数用率的算法是:100*((totalCpuTimeS-totalCpuTimeF) - (idelS-idelF)) / (totalCpuTimeS - totalCpuTimeF)</p> <p> </p> <pre> <code class="language-java">if (null != totalCpu2 && totalCpu2.size() > 0) { processCpuRatio = fomart.format(100 * ((double) (processCpu - processCpu2) / ((double) (totalCpu.get(0) - totalCpu2.get(0))))); for (int i = 0; i < (totalCpu.size() > totalCpu2.size() ? totalCpu2.size() : totalCpu.size()); i++) { String cpuRatio = "0.00"; if (totalCpu.get(i) - totalCpu2.get(i) > 0) { cpuRatio = fomart .format(100 * ((double) ((totalCpu.get(i) - idleCpu.get(i)) - (totalCpu2.get(i) - idleCpu2.get(i))) / (double) (totalCpu .get(i) - totalCpu2.get(i)))); } totalCpuRatio.add(cpuRatio); totalCpuBuffer.append(cpuRatio + Constants.COMMA); } } else { // 保存前一次的cpu使用情况 processCpuRatio = "0"; totalCpuRatio.add("0"); totalCpuBuffer.append("0,"); totalCpu2 = (ArrayList<Long>) totalCpu.clone(); processCpu2 = processCpu; idleCpu2 = (ArrayList<Long>) idleCpu.clone(); }</code></pre> <p> </p> <p>来自:http://www.jianshu.com/p/220b2873cb4e</p> <p> </p>