Android內存解析

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的前提下能更好的尋求到合理的優化方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章