OOM机制是机器底层的一种强制保鲜,在OOM发生的时候内核会排序强制杀掉进程来保证系统的继续运行,同样这种OOM异常容易发生在低内存机器上,比如512M。
首先系统会根据程序是否是空进程(已经由用户关闭的不带有任何服务和provider的进程),是否有服务,是否有provider,是否为前台进程,来排序,可以输入 adb shell dumpsys meminfo来查看,列出信息中的Total PSS by OOM adjustment:就是系统为程序的OOM排序结果,OOM异常的时候会根据这个表单从下网上杀掉进程释放内存。
部分概念
1.1 名词概念:
- 虚拟内存
进程空间内的虚拟内存地址,理论上32位cpu一个进程有4GB的虚拟内存可以使用。 - 物理内存
就是真正写的到内存条上的,真实地址对进程不可见,由操作系统把虚拟内存地址映射到物理内存地址。 - Size
指的就是分配了多少虚拟内存 - mmap
一种内存映射文件的方法。
mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。
android程序内存被分为2部分:native
和dalvik
,dalvik就是java堆,普通java对象是在java堆分配,而bitmap是直接在native上分配,对于内存的限制是 native+dalvik 不能超过最大限制。Android程序内存一般限制在16M,当然也有24M的。
1.2 内存指标概念
- VSS
Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
是单个进程全部可访问的地址空间 - RSS
Resident Set Size 实际使用物理内存(包含共享库占用的内存)
是单个进程实际占用的内存大小,对于单个共享库, 尽管无论多少个进程使用,实际该共享库只会被装入内存一次。 - PSS
Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存) - USS
Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
USS 是一个非常非常有用的数字, 因为它揭示了运行一个特定进程的真实的内存增量大小。如果进程被终止, USS 就是实际被返还给系统的内存大小。
USS 是针对某个进程开始有可疑内存泄露的情况,进行检测的最佳数字。怀疑某个程序有内存泄露可以查看这个值是否一直有增加。
内存的大小关系:VSS >= RSS >= PSS >= USS
dumpsys meminfo
PS:多个设备连接时cmd执行指令会报错:多设备连接,指定设备号也没用。
adb shell dumpsys meminfo
:获取内存使用情况
结果主要包含以下4个部分:
adb shell dumpsys meminfo [pkg/pid]
:查看指定进程或包名的内存使用情况
-
Uptime
表示启动到现在的时长,不包含休眠的时间,单位毫秒(ms) -
Realtime
表示启动到现在的时长,包含休眠的时间,单位毫秒(ms) -
Native Heap
Native代码分配的内存,虚拟机和Android框架分配内存。Native代码:即非Java代码分配的内存。
指C中malloc出来的堆空间。
扩展:c++申请的内存为native process,java申请的内存:java process -
Dalvik Heap
Java对象分配的占据内存。 -
Dalvik Other
类数据结构和索引占据内存。 -
Stack:栈内存。
-
Ashmem:
匿名共享内存(Anonymous Shared Memory-Ashmem)不以dalvik- 开头的内存区域,通过分配一个多个进程可以共享的带名称的内存块来提供共享内存。
Android匿名共享内存是基于Linux共享内存的,它们都是在tmpfs文件系统上新建文件,并将其映射到不同的进程空间,从而达到共享内存的目的,只是,Android在Linux的基础上进行了改造,并借助Binder+fd文件描述符实现了共享内存的传递。
参考文章:
① Android匿名共享内存(Ashmem)原理(简书——看书的小蜗牛)
② Android系统匿名共享内存Ashmem简要介绍和学习计划 -
Other dev
内部driver占用的内存。 -
.so mmap
C库代码占用的内存。 -
.jar mmap
java文件代码占用的内存。 -
.apk mmap
apk代码占用的内存。 -
.ttf mmap
ttf字体文件代码占用的内存。 -
.dex mmap
dex文件代码占用的内存。类函数的代码和常量占用的内存,dex mmap是映射classex.dex文件,Dalvik虚拟机从dex文件加载类信息和字符串常量等。Dex文件有索引区和Data区 -
Other mmap
其它文件占用的内存 -
Objects
是统计App内部组件对象个数,其中Views、ViewRootImpl以及Activities个数,在Activity onDestroy后应该都会回收清零,如果onDestroy调用后这几个对象个数没有清零,就可能发生了内存泄漏。
附:
adb shell dumpsys [options]
■ meminfo
内存
■ cpuinfo
CPU
■ gfxinfo
帧率
■ display
显示
■ power
电源
■ battery
电池
■ batterystats
电池状态
■ location
位置
■ alarm
闹钟
■ account
accounts
■ activity
显示所有的activities的信息
■ window
显示键盘,窗口和它们的关系
■ wifi
显示wifi信息
资料来源们:
android dumpsys meminfo 详解(博客园——不言不语技术)
android dumpsys meminfo 详解(CSDN——凯文的内存)
对APP进行dumpsys meminfo内存分析解读(CSDN——manok)