Android获取当前应用的运行内存
题外话,最近在给H5游戏做一个缓存的框架,有个小需求是在WebView界面上显示一个调试框,实时显示缓存信息,包括显示当前的内存大小。本来想网上应该一堆的博客介绍的。心想这样子就美滋滋了,也没多想。但是MMP,一把辛酸泪。
把代码拷贝下来后,发现内存获取显示不对,一直往上飙,100M,200M,300M,400M。但是,Android Profiler 内存分析消耗是不变的,真是日了狗了。没办法找原因啊,网上看了看了一大堆分析的,就想问句,代码有验证过么就发出来?!!!
最后,还得自己解决。分析了下Android Profiler 的内存结构:
由这几部分组成,然后大家再跟看看系统源码的android.os.Debug.MemoryInfo的这个类,哈哈哈,刚好也有相关的内存结构分类说明:(大家自己翻译理解,我不多说了)
/**
* Returns the value of a particular memory statistic or {@code null} if no
* such memory statistic exists.
*
* The following table lists the memory statistics that are supported.
* Note that memory statistics may be added or removed in a future API level.
*
*
*
*
* Memory statistic name
* Meaning
* Example
* Supported (API Levels)
*
*
*
*
* summary.java-heap
* The private Java Heap usage in kB. This corresponds to the Java Heap field
* in the App Summary section output by dumpsys meminfo.
* {@code 1442}
* 23
*
*
* summary.native-heap
* The private Native Heap usage in kB. This corresponds to the Native Heap
* field in the App Summary section output by dumpsys meminfo.
* {@code 1442}
* 23
*
*
* summary.code
* The memory usage for static code and resources in kB. This corresponds to
* the Code field in the App Summary section output by dumpsys meminfo.
* {@code 1442}
* 23
*
*
* summary.stack
* The stack usage in kB. This corresponds to the Stack field in the
* App Summary section output by dumpsys meminfo.
* {@code 1442}
* 23
*
*
* summary.graphics
* The graphics usage in kB. This corresponds to the Graphics field in the
* App Summary section output by dumpsys meminfo.
* {@code 1442}
* 23
*
*
* summary.private-other
* Other private memory usage in kB. This corresponds to the Private Other
* field output in the App Summary section by dumpsys meminfo.
* {@code 1442}
* 23
*
*
* summary.system
* Shared and system memory usage in kB. This corresponds to the System
* field output in the App Summary section by dumpsys meminfo.
* {@code 1442}
* 23
*
*
* summary.total-pss
* Total PPS memory usage in kB.
* {@code 1442}
* 23
*
*
* summary.total-swap
* Total swap usage in kB.
* {@code 1442}
* 23
*
*
*
*/
public String getMemoryStat(String statName) {
switch(statName) {
case "summary.java-heap":
return Integer.toString(getSummaryJavaHeap());
case "summary.native-heap":
return Integer.toString(getSummaryNativeHeap());
case "summary.code":
return Integer.toString(getSummaryCode());
case "summary.stack":
return Integer.toString(getSummaryStack());
case "summary.graphics":
return Integer.toString(getSummaryGraphics());
case "summary.private-other":
return Integer.toString(getSummaryPrivateOther());
case "summary.system":
return Integer.toString(getSummarySystem());
case "summary.total-pss":
return Integer.toString(getSummaryTotalPss());
case "summary.total-swap":
return Integer.toString(getSummaryTotalSwap());
default:
return null;
}
}
/**
* Returns a map of the names/values of the memory statistics
* that {@link #getMemoryStat(String)} supports.
*
* @return a map of the names/values of the supported memory statistics.
*/
public Map getMemoryStats() {
Map stats = new HashMap();
stats.put("summary.java-heap", Integer.toString(getSummaryJavaHeap()));
stats.put("summary.native-heap", Integer.toString(getSummaryNativeHeap()));
stats.put("summary.code", Integer.toString(getSummaryCode()));
stats.put("summary.stack", Integer.toString(getSummaryStack()));
stats.put("summary.graphics", Integer.toString(getSummaryGraphics()));
stats.put("summary.private-other", Integer.toString(getSummaryPrivateOther()));
stats.put("summary.system", Integer.toString(getSummarySystem()));
stats.put("summary.total-pss", Integer.toString(getSummaryTotalPss()));
stats.put("summary.total-swap", Integer.toString(getSummaryTotalSwap()));
return stats;
}
到这里,我们就可以解决问题了,只需要获取到对应的信息就可以了,下面代码供大家参考下。
@TargetApi(Build.VERSION_CODES.M)
private double getRunningMemory() {
double mem = 0.0D;
try {
// 统计进程的内存信息 totalPss
final Debug.MemoryInfo[] memInfo = activityManager.getProcessMemoryInfo(new int[]{Process.myPid()});
if (memInfo.length > 0) {
/**
* 读取内存信息,跟Android Profiler 分析一致
*/
String java_mem = memInfo[0].getMemoryStat("summary.java-heap");
String native_mem = memInfo[0].getMemoryStat("summary.native-heap");
String graphics_mem = memInfo[0].getMemoryStat("summary.graphics");
String stack_mem = memInfo[0].getMemoryStat("summary.stack");
String code_mem = memInfo[0].getMemoryStat("summary.code");
String others_mem = memInfo[0].getMemoryStat("summary.system");
final int dalvikPss = ConvertUtils.convertToInt(java_mem,0)
+ ConvertUtils.convertToInt(native_mem,0)
+ ConvertUtils.convertToInt(graphics_mem,0)
+ ConvertUtils.convertToInt(stack_mem,0)
+ ConvertUtils.convertToInt(code_mem,0)
+ ConvertUtils.convertToInt(others_mem,0);
if (dalvikPss >= 0) {
// Mem in MB
mem = dalvikPss / 1024.0D;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return mem;
}
/**
* 转化为int
* @param value 传入对象
* @param defaultValue 发生异常时,返回默认值
* @return
*/
public final static int convertToInt(Object value, int defaultValue){
if (value == null || "".equals(value.toString().trim())){
return defaultValue;
}
try {
return Integer.valueOf(value.toString());
}catch (Exception e){
try {
return Integer.valueOf(String.valueOf(value));
}catch (Exception e1) {
try {
return Double.valueOf(value.toString()).intValue();
}catch (Exception e2){
return defaultValue;
}
}
}
}
实践验证上图:
结语:
当遇到问题的时候,要多看看源码信息,答案就在其中。