Ashmem匿名共享內存java
Android的匿名共享內存(Ashmem)機制基於Linux內核的共享內存,可是Ashmem與cache shrinker關聯起來,增長了內存回收算法的註冊接口,所以Linux內存管理系統將再也不使用內存區域加以回收。Ashmem之內核驅動的形式實現,在文件系統中建立/dev/ashmem設備文件。若是進程A與進程B須要共享內存,進程A可經過open打開該文件,用ioctl命令ASHMEM_SET_NAME和ASHMEM_SET_SIZE設置共享內存的名稱和大小。mmap使用handle得到共享的內存區域;進程B使用一樣的handle,由mmap得到同一塊內存。handle在進程間的傳遞可經過Binder等方式實現。android
爲有效回收,須要該內存區域的全部者通知Ashmem驅動。經過用戶,Ashmem驅動程序,以及Linux內存管理系統的協調,使內存管理更適應嵌入式移動設備內存較少的特色。Ashmem機制輔助內存管理系統來有效管理再也不使用的內存,同時經過Binder進程通訊機制實現進程間的內存共享。算法
Ashmem不但以/dev/ashmem設備文件的形式適應Linux開發者的習慣,並且在Android系統運行時和應用程序框架層提供了訪問接口。其中,在系統運行時提供了C/C++調用接口,在應用程序框架層提供了Java調用接口。而實際上,應用程序框架層的Java調用接口是經過JNI方法來調用系統運行時的C/C++調用接口的,最後進入到內核空間的Ashmem驅動程序中。安全
LMK機制框架
Android的軟件協議棧由操做系統內核,中間件與應用程序組成。雖然基於Linux操做系統內核,android進程的內存管理與Linux仍有區別。Android的應用程序由java語言編寫,運行於Java虛擬機之上,可是,Android的java虛擬機Dalvik與傳統的Java虛擬機是有區別的。Dalvik採用基於寄存器的虛擬機優化實現,確保多個虛擬機實例同時運行,藉助Linux內核服務,實現安全保護,線程管理,底層進程與內存管理等功能。Dalvik虛擬機運行.dex格式的Dalvik可執行文件。.dex格式由android工具將java格式的class文件轉化而來,而且進一步優化,下降內存佔用。ide
Android的每一個應用程序都有一個獨立的Dalvik虛擬機實例,而且運行於獨立的進程空間。Android運行時(Runtime)與虛擬機都運行於Linux操做系統之上,藉助操做系統服務進行底層內存管理並訪問底層設備的驅動程序。函數
可是,不一樣於Java與.NET,Android運行時同時管理進程的生命週期。爲確保應用程序的響應性,能夠在必要時中止甚至殺死某些進程,向更高優先級的進程釋放資源。具體原則以下:工具
應用程序的進程優先級決定哪些進程能夠被殺死以釋放資源,而應用程序的優先級取決於其組件的最高優先級。優化
當兩個進程具有相同的優先級時,一般處於低優先級時間最長的進程先被殺死,以釋放資源。spa
進程優先級同時取決於進程間的依賴關係:例如,第一個進程依賴於第二 個進程提供的服務(Services)或內容提供者(Content Provider),則第二個進程至少具有與第一個進程一樣的優先級。
Android系統能夠同時運行多個應用程序。因爲啓動與運行一個應用程序須要必定的時間開銷,爲了加快運行速度,Android並不會當即殺死一個退出的程序,而是讓它駐留在內存中,以便下次運行時迅速啓動。可是,隨着程序愈來愈多,內存會出現不足。當Android系統須要某一進程釋放資源爲其餘進程所用時,系統使用所謂的「LowMemoryKiller」殺死進程以釋放資源。LowMemoryKiller在Linux內核中實現,按程序的重要性來決定殺死哪個應用。所以,必須妥善設置進程的優先級,不然該進程可能在運行過程當中被系統殺死。
Android自動管理打開並運行於後臺的應用程序,單個程序都有一個oom_adj值,值越小,優先級越高,被殺死的可能性越低。Android將程序的重要性分紅幾類。
1. 前臺進程(Active Process):oom_adj值爲0。前臺進程爲正在與用戶交互 的應用程序。爲響應前臺進程,Android可能要殺死其餘進程以收回資源。前臺進程分爲如下幾類:
活動(Activity)正在前臺接收用戶輸入事件。
活動,服務與廣播接收器正在執行一個onReceive事件處理函數。
服務正在執行onStart,onCreate或onDestroy事件處理函數。
2. 已啓動服務的進程(Started Service Process):oom_adj值爲0。這類進程包含一個已啓動的服務。服務並不直接與用戶輸入交互,所以服務的優先級低於可見活動的優先級。可是,已啓動服務的進程仍然被認爲是前臺進程,只有在活動及可見活動須要資源時,已啓動服務的進程纔會被殺死。
3. 可見進程(Visible Process):oom_adj值爲1。活動(Activity)是可見的,但並不在前臺,或者不響應用戶的輸入。例如,Activity被非全屏的Activity或透明的Activity所遮擋。包含此類可見Activity的進程被稱爲可見進程。只有在很是少有的極端狀況下,此類進程纔會被殺死以釋放資源。
4. 後臺進程(Background Process):oom_adj值爲2。這類進程不包含任何可見的活動與啓動的服務。一般大量後臺進程存在時,系統會採用(last-seen-firest-killl)後見先殺的方式,釋放資源供前臺進程使用。
5. 主界面(Home Process):oom_adj值爲4。
6. 隱藏進程(Hidden Process):oom_adj值爲7。
7. 內容提供者(Content Provider):oom_adj值爲14。
8. 空進程(Empty Process):oom_adj值爲15。既不提供服務,也不提供內容的進程。
Android系統一般有一個內存警惕值與oom_adj值的對應表:每一個內存警惕值對應一個oom_adj值。當系統內存低於警惕值時,全部大於oom_adj值的進程均可被殺死!內存警惕與oom_adj值對應關係以下表:
進程各種 |
oom_adj值 |
內存警惕值(以4KB爲單位) |
前臺進程/服務進程 |
0 |
1536 |
可見進程 |
1 |
2048 |
後臺進程 |
2 |
4094 |
隱藏進程 |
7 |
5120 |
內容提供者 |
14 |
5632 |
空進程 |
15 |
6144 |
當可用內存小於6144 * 4K = 24MB時,開始殺死全部的空進程,當可用內存小於5632 * 4K = 22MB時,開始殺死全部內容提供者與空進程。上表的設置能夠經過修改如下兩個文件實現:
/sys/module/lowmemorykiller/parameters/adj
/sys/module/lowmemorykiller/parameters/minfree
例如,把minfree最後一項改成32 * 1024,那麼當可用內存小於128MB時,就開始殺全部的空進程。
可是,當過多進程在內存中未被釋放,系統反應速度會下降,形成用戶滿意度下降。用戶能夠自行使用如task killer與task Manager之類的工具軟件手動殺死沒必要要的後臺進程與空進程,強制釋放資源。