Android内存分析
内存表达方式
- VSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
- RSS- Resident Set Size 实际使用物理内存(包含共享库占用的内存)
- PSS- Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
- USS- Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
我们在Android手机的设置页面看到的内存占用情况,就是使用了PSS标准。同时在内存优化过程中,也经常被用作衡量指标。
PSS内存查看方式
- adb shell dumpsys meminfo
- 手写测试程序:
- activitymanager.getRunningAppProcesses():
- memoryinfo[0].getTotalPss():
dumpsys meminfo详述
dumpsys-meminfo.png接下来,我们对上图中的信息做详细说明:
-
Dalvik Heap
在app中由Dalvik申请的内存。
Pss Total包含了Zygote申请的内存(只不过Pss是按照共享数均分给每个进程)。
这里做下说明,android下所有app的进程均是fork自Zygote,从Zygote进程 fork 时,子进程完全拷贝了Zygote进程的虚拟内存空间(包括加载的so占用、resource资源占用、主动申请等内存空间等)。但当继承自Zygote进程的内存被修改时,由于copy-on-write,会申请新的内存空间,这就会形成Private Dirty内存。当继承自Zygote进程的内存没被修改时,是不用分配额外的内存空间。
-
Private Dirty
它是app自己提交的内存总数,包含了app自己主动申请的和修改了的继承自Zygote的内存。
其实,Private Dirty表示了该进程私有的,不跟disk数据一致的内存段。例如堆(heap),栈(stack),bss段。注:在新平台上,用于管理Dalvik的内存(如, just-in-time compilation (JIT) and GC bookkeeping)不再像以前一样归到 Dalvik Heap,而是归类到 Dalvik Other。
-
Heap Size/Alloc/Free
Heap Alloc是(Dalvik、native)app申请的内存记录,包括了Private Dirty和继承自Zygote的(多进程共享的)内存。所以,它是比Pss Total和Private Dirty都要大的。 -
Private clean
它包括该进程独自使用的so和dex。Clean内存的好处是在内存紧张时,可以释放物理内存。因为是clean的,所以不需要写回到disk,只需要下次读取该内存(导致缺页错误)时再从disk读入。 -
Shared Clean
它表示多个进程共享的so和dex。关于so库的加载,第一次是以MAP_PRIVATE参数 mmap so,内存都是private clean的。如果另外一个进程mmap了同一个so,就变成shared clean了。
DDMS:MemoryMonitor
Android自带的内存查看工具,查看的是Dalivik Heap Size/Alloc/Free。
内存优化工具:MAT
强大的内存分析工具,MAT,分析的文件hprof文件有以下获取方式(都需要使用hprof-conv工具转换):
- DDMS 中dump出来
- 函数:dumpHprofData()生成
使用MAT分析内存时,会遇到一些术语比较难懂的术语,这里简单说明下:
-
RetainedHeap:
它表示如果一个对象被释放掉,那会因为该对象的释放而减少引用进而被释放的所有的对象(包括被递归释放的)所占用的heap大小。(又开始Histogram中不显示Retained heap,需要点击那个计算器的按钮才会计算出来)。这里最小的粒度是类级别的。 -
Dominator Tree:
它表示对象引用树(原来是用图表示对象引用关系)。 -
MAT中点击右键
- 在List objects中选择with outgoing references和with incoming references。这是个真正的引用图的概念,表示该对象的出节点(被该对象引用的对象)和入节点(引用到该对象的对象)。
- Path to GC Roots:GC roots是可能导致GC的节点。这个Path则是从这些GC root节点中的某个到当前对象的最短引用路径。对这个如何计算不是很确定,我想应该是根据引用树而不是dominator tree。
参考:
https://developer.android.com/studio/profile/investigate-ram.html#LogMessages
https://www.youtube.com/watch?v=ptjedOZEXPM