博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android内存测试方法梳理和实现原理简析
阅读量:5963 次
发布时间:2019-06-19

本文共 2034 字,大约阅读时间需要 6 分钟。

废话不说,直接上干货。

1:代码的方式

代码中使用Debug的getMemoryInfo(Debug.MemoryInfo memoryInfo)或ActivityManager的MemoryInfo[] getProcessMemoryInfo(int[] pids)

ActivityManager mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);Debug.MemoryInfo[] memoryInfoArray = mAm.getProcessMemoryInfo(pids);复制代码

MemoryInfo对象中可以看看详细的内存信息,字段如下: 目前很多内存测试工具都是采用这种方式,如哆啦A梦、GT等。这种方式简单方便

2:dumpsys 命令

adb shell dumpsys meminfo package_name|pid复制代码

一般关注关PSS列的这几个字段:

  • Native Heap:JNI层的内存
  • Dalvik Heap:Java层的内存分配情况
  • Total PSS :应用真正占据的内存大小

一般公司测试都是会采用这种方式获取内存数据的

3:smaps文件

Linux在2.6版本之后有一个proc伪文件,在它下面记录各种信息,其中在proc/pid/smaps记录某个pid的内,smaps记录内存详细的使用情况。使用下面的命令可以读文件的值

cat /proc/pid/smaps复制代码

文件格式如下:

文件字段意义:

  • 400ca000-400cb000:本段虚拟内存的地址范围
  • r-xp :文件权限,r(读)、w(写)、x(执行)、p表示私有,s代表共享,如果不具有哪项权限用"-"代替
  • 00000000 :映射文件的偏移量
  • b3:11 :文件设备号
  • 1345 :被映射到虚拟内存文件的映索节点
  • /system/lib/libplddbgutil.so:文件名称
  • Size:相应虚拟地址空间的大小
  • RSS: 正在使用的物理内存的大小
  • Shared_Clean: Rss中和其他进程共享的未使用页数
  • Shared_Dirty: Rss和其他进程共享已经使用的页数
  • Private_Clean: Rss私有区域未使用的页数
  • Private_Dirty: Rss私有区域已经使用的页数

smaps文件一般有啥作用呢,譬如我们通过dumpsys meminfo 获取内存时,发现某一项内存数据异常,想弄清楚数据都是有哪些文件产生,我们就可以通过读取smaps详细排查。

4:源码分析

我们执行dumpsys memInfo 命令后的代码执行流程是怎样的呢,dumpsys命令会根据传进来的参数通过函数checkService来找到具体的service, 然后执行该service的dump方法,最总达到dump service的目的。

那我们传进入的memInfo对应的是哪个service呢,这个我们需要查看ActivityManagerService.Java类,搜索一下memInfo,最后我们发现它对应的service是MemBinder。

我们点击MemBinder类看类内部的实现

方法内部首先会进行android.Manifest.permission.DUMP权限检查,最终调用 dumpApplicationMemoryUsage方法,我们再看dumpApplicationMemoryUsage方法做了哪些操作

这个方法内容比较多,这里我们只显示了它最终调的地方,我们最终发现最后会调用android.os.Debug.java类。

其实会调用android.os.Debug.java类调用了大量的Native方法实现的,android.os.Debug.java对应的native文件是android_os_Debug.cpp,上面的Debug.getMemoryInfo(pid, mi)实际上最后调用了 android_os_Debug.cpp的android_os_Debug_getDirtyPagesPid方法

android_os_Debug_getDirtyPagesPid方法调用了load_maps(int pid, stats_t* stats)方法

load_maps中是通过读取smaps文件内容,到此dumpsys memInfo的实现就非常清晰了。

第一种代码的实现方式,其实最后走的流程和上面的是一样的。

android_os_Debug.cpp地址:

5:内存测试关注的点

1.内存是否持续上涨:进入某项功能内存增长,退出功能时内存是否下降

2.是否频繁的GC:频繁的gc可能是因为你的程序内存碎片导致的,这也是需要优化的一个方向

3.内存的峰值是否在单个应用允许的最大值之内

转载地址:http://fljax.baihongyu.com/

你可能感兴趣的文章
从前后端分离到GraphQL,携程如何用Node实现?\n
查看>>
Linux Namespace系列(09):利用Namespace创建一个简单可用的容器
查看>>
博客搬家了
查看>>
Python中使用ElementTree解析xml
查看>>
jquery 操作iframe、frameset
查看>>
解决vim中不能使用小键盘
查看>>
jenkins权限管理,实现不同用户组显示对应视图views中不同的jobs
查看>>
我的友情链接
查看>>
批量删除用户--Shell脚本
查看>>
Eclipse Java @Override 报错
查看>>
知道双字节码, 如何获取汉字 - 回复 "pinezhou" 的问题
查看>>
linux中cacti和nagios整合
查看>>
Python高效编程技巧
查看>>
js中var self=this的解释
查看>>
Facebook 接入之获取各个配置参数
查看>>
linux的日志服务器关于屏蔽一些关键字的方法
查看>>
事情的两面性
查看>>
只要会营销,shi都能卖出去?
查看>>
sed单行处理命令奇偶行输出
查看>>
VC++深入详解学习笔记1
查看>>