Android内存解析<一>

来源:互联网 发布:淘宝手机单怎么刷视频 编辑:程序博客网 时间:2024/06/11 00:02

Android内存解析<一>

最近有空在家休息,决定乘此机会写写这些年学习中积累的一些知识,算是一个总结,方便后续用到时可以来此翻看。最近半年都是在与Android平台的Memory打交道,所有就先从Android Memory的部分开始总结。关于Memory我主要从如下两个方面来写:
  • Android平台Memory分析
  • Android进程Memory分析

大的方向是两个,Android平台的开发者以及设备厂商们会比较关心整个Android手机整体Memory的使用状况,比如kernel memory的使用、user space memory的使用以及free memory状况等。而App的开发者们一般侧重在对进程Memory的分析,或者更多的是在分析Heap memory的使用。
两个方向的分析过程中会涉及到一些其他的memory知识,比如Java虚拟机的Memory管理、Linux内存管理、C/C++程序的Memory等,这部分在提到时再单独链接相应的文章进来说明。


Android平台Memory分析

Android平台的开发者们在开发一个产品时,针对市场会有不同的定位,对内存的选型也会有差异,例如选用1G、2G、4G的RAM。不同RAM size的产品在Feature上会稍有差别,例如1G的产品会支持更少的Feature, 最高只开HD的屏,不开FHD的屏等等。总的来说对Memory的使用是精打细算,在RAM固定的状况下,既希望提供出更丰富的功能,又希望能省下更多的Free memory保证系统的流畅性,力争用户体验比对手更优。所以对于系统中各个部分Memory的使用状况必须非常清晰,带着这个想法,我尝试把了解到的一些内容记录下来。

一、Memory Layout

从整体来看我们可以把Android设备所使用的Memory看成两部分,一部分是预留给其他硬件设备的Memory,一部分是Linux系统可以看到的Memory。

这里写图片描述

  • 1. Hardware reserved memory
    给其他硬件设备预留的Memory是Linux系统无法访问到的,这部分主要包含为Modem、Frame buffer、TEE以及WiFi 等chip预留的一些Memory。
    这里写图片描述

    那这部分的Memory有多大呢,我们不妨来看看。例如拿我手边2G的设备查看iomem, 可以计算出所有的System RAM为1936M, 则:
    HW reserved = RAM Size(2048M) - System RAM(1936M) = 112M

    这里写图片描述

    HW Reserved中占比最大的一般是Modem,这部分也与Modem本身支持的模数等都有关系,各Modem厂家本身的代码实现差异也不同,size大小各有差异。
    Frame buffer的大小则比较固定,主要由LCM的Resolution决定。
    TEE是关于手机安全相关,例如指纹识别等,所以跟支持的功能有强相关。
    另外System RAM以及HW reserved memory的计算方法在不同平台上由于有一些客制化,导致可能存在一些差异,这部分我们暂且不表。

  • 2. System RAM

    System RAM的部分是主Chip(或者可以叫AP端)可以看到的Memory 。这部分我们也先将其看成两个部分。

    这里写图片描述

    2.1. Kernel reserved

    第一部分是Kernel reserved memory。主要是Kernel image、 kernel data、用于Linux memory管理的page array以及其他一些杂项。这部分是固定开销,没有办法把Memory再要回来给系统使用。如果想优化成小的size则需要深入kernel。

    这里写图片描述

    kernel的大小也可以从iomem中查看到,例如这边看到的kernel code是13M, kernel data是4.5M,Kernel的大小与linux kernel版本相关。

    这里写图片描述

    2.2. MemoryTotal
    第二部分我这里直接称其为MemoryTotal。这是Linux系统真正能自由分配使用的Memory,也是我们所知的Linux Buddy system按page管理的Memory。MemoryTotal的大小我们可以很方便的查看到,如下我手边的一台2G的设备是1886M:

    这里写图片描述

    反推一下,从MemoryTotal我们也可以得到kernel reserved的大小:
    kernel reserved = System Ram(1936M) - MemoryTotal(1886M) = 50M

    我们已经知道MemoryTotal是Android系统上使用page管理,可以真正使用起来的Memory,那这里面具体又是哪些模块在使用呢?还是使用简单的图形来表示这一块Buddy system所管理的memory区域的组成:

    这里写图片描述

    把MemoryTotal分三个部分来看:

    2.2.1. kernel used

    第一个部分是kernel used, 可以认为是kernel space中的memory用量。列出如下:
    这里写图片描述

    从meminfo中可以看到部分kernel memory的使用状况:

    这里写图片描述

    对于ION及3D memory,由于基本上是user space的process在使用,只是在kernel space进行了分配管理。所以可以从process的memory分析中去查看这两个部分。

    2.2.2. User space memory

    第二部分是User space的memory用量,也是我们最为熟悉的所有的进程(包括java层以及native层所有process)的Memory使用量。process的使用状况可以从dumpsys meminfo中获取到,从这个信息中我们可以很清楚的把握到每个process以及所有process的memory的使用状况。如果对于单个process的memory有疑问则可以再使用后续App Memory的分析方法做进一步分析。

    这里写图片描述

    把所有process的memory用量进行加总,则是user space中所有process目前memory的使用量。

    Process Name KB MB system 84022 82.05273438 com.android.systemui 80856 78.9609375 com.sohu.inputmethod.sogou 51471 50.26464844 com.android.settings 46759 45.66308594 … … … Total 860334 840.1699219

    另外还有一种方法可以计算出所有process的pss用量,通过adb shell cat /proc/meminfo中的AnonPages和Mapped两项信息:

    Total PSS = AnonPages(625408)+ Mapped(193284) = 818692KB.
    (这边计算稍有差异是因为抓取memory的时间点有差异)这边采用的计算方法是把所有的process使用的memory分成了两种类型,一种是Anonymous memory,例如stack, heap等,另一种是Mapped Memory, 例如RO code, RO data等。

    2.2.3. Free Memory

    第三个部分Free是Linux系统尚未分配出去的page Memory,对应meminfo中的MemFree。

二、Cache Free Memory

各平台或设备厂家在开发过程中会不断优化各模块Memory的用量,以期望能塞进更丰富的功能,同时期望为用户留有足够的剩余Memory。如果剩余的Memory过少,意味着可同时运行的App数目会减少,新的App在起来时,需要LMK kill掉其他的process才能获取到足够的Memory,如果想再回到之前的App时,相当于First launch, 必然会影响到performance。
所以工程师们会一直关注一个重要的指标:Cache Free。要如何理解cache free呢?我们可以这样来思考,当一个新的App起来的时候,还能要到多少的memory?首先如下三项Memory是可以直接要到的:
1. MemFree
2. Buffers
3. Cached

这里写图片描述

因此一些初步的Free Memory评估会直接对上面三项Memory加总。
另外还有一部分Background process(Adj >=9),优先级比较低,认为是可以被回收的。这部分Memory可以从adb shell dumpsys meminfo中查看到,例如:

这里写图片描述

Google在考虑Free memory时,同时还考虑了系统performance问题。由于前面第三项Cached部分还包含了各进程file mapped memory,而回收掉file mapped memory必然会影响process的performance。所以也考虑在计算Cache free时需要减去Mapped memory.

当然,对于Cache free的计算都是估算,系统是复杂的,很难做到精确的计算,而且精确的意义也不大。

在认识到Memory的使用状况以及Cache Free的评价指标后,工程师们要做的就是努力优化各模块的Memory用量。下一篇我会从Process的角度来介绍单个进程中Memory的使用状况,在完整把握Process Memory的前提下能更好的寻求到合理的优化方案。

原创粉丝点击