美文网首页
Android内存分析

Android内存分析

作者: joyousx | 来源:发表于2016-12-08 15:09 被阅读0次

    内存表达方式

    • 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

    相关文章

      网友评论

          本文标题:Android内存分析

          本文链接:https://www.haomeiwen.com/subject/oocsmttx.html