且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

移动App性能测评与优化1.4.3 zygote共享内存机制

更新时间:2022-09-27 19:35:57

1.4.3 zygote共享内存机制

上一小节介绍了应用各部分内存的含义,读者对dumpsys meminfo输出的大部分数据都能够有所理解。但dumpsys meminfo工具还会输出Heap Size/Alloc/Free部分的数值。我们知道这些数值是Dalvik虚拟机统计的内存堆的使用量,但这些数值是如何对应到Pss内存上的?比如Heap Alloc和Heap Pss往往相差不远,那是不是可将其看做基本等同的呢?下面我们试图解释这几项数值之间的关系。

由于虚拟机运行时并不区分某个对象实例是Android框架共享的还是应用独有的,Heap Alloc统计的是由虚拟机分配的所有应用实例的内存,所以会将应用从zygote共享的部分也算进去,于是Heap Alloc值总是比实际物理内存使用值要大。

Heap Alloc虽然反映了Java代码分配的内存,但存在框架造成的失真。除此之外,进程还有许多其他部分也需要使用内存。为了准确了解应用消耗的内存,我们要从进程角度而不是虚拟机角度来进行观察。

Pss表示进程实际使用的物理内存,是由私有内存加上按比例分担计算的各进程共享内存得到的值。例如,如果有三个进程都使用了一个消耗30KB内存的so库,那么每个进程在计算这部分Pss值的时候,只会计算10KB。总的计算公式是:

Dalvik Pss内存 = 私有内存Private Dirty

                              + (共享内存Shared Dirty / 共享的进程数)

从实际含义来讲,Private Dirty部分存放的是应用新建(new)出来的对象实例,是每个应用所独有的,不会再共享。Shared Dirty部分主要是zygote加载的Android框架部分,会被所有Android应用进程共享。通常进程数的值在10~50的范围内。

Pss是一个非常有用的数值,如果系统中所有进程的Pss相加,所得和即为系统占用内存的总和。但要注意的是,进程的Pss并不代表进程结束后系统能够回收的内存大小。