談談Android的內存管理機制
- 分配機制:為每一個任務(進程)分配一個合理大小的內存塊,保證每一個進程能夠正常的運行,同時確保進程不會佔用太多的內存。
- 回收機制:當系統內存不足的時候,需要有一個合理的回收再分配機制,以保證新的進程可以正常運行。回收時殺死那些正在佔用內存的進程,OS需要提供一個合理的殺死進程機制。
下面分別從 分配 和 回收 兩方面來描述Android的內存管理機制:
分配機制
Android為每個進程分配內存時,採用彈性的分配方式,即剛開始並不會給應用分配很多的內存,而是給每一個進程分配一個「夠用」的內存大小。這個大小值是根據每一個設備的實際的物理內存大小來決定的。隨著應用的運行和使用,Android會為進程分配一些額外的內存大小。但是分配的大小是有限度的,系統不可能為每一個應用分配無限大小的內存。
總之,Android系統需要最大限度的讓更多的進程存活在內存中,以保證用戶再次打開應用時減少應用的啟動時間,提高用戶體驗。
回收機制
Android對內存的使用方式是「盡最大限度的使用」,只有當內存水足的時候,才會殺死其它進程來回收足夠的內存。但Android系統否可能隨便的殺死一個進程,它也有一個機制殺死進程來回收內存。
Android殺死進程有兩個參考條件:
1. 進程優先順序
Android為每一個進程分配了優先組的概念,優先組越低的進程,被殺死的概率就越大。根據進程的重要性,劃分為5級:
1)前台進程(Foreground process)
用戶當前操作所必需的進程。通常在任意給定時間前台進程都為數不多。只有在內存不足以支持它們同時繼續運行這一萬不得已的情況下,系統才會終止它們。
2)可見進程(Visible process)
沒有任何前台組件、但仍會影響用戶在屏幕上所見內容的進程。可見進程被視為是極其重要的進程,除非為了維持所有前台進程同時運行而必須終止,否則系統不會終止這些進程。
3)服務進程(Service process)
儘管服務進程與用戶所見內容沒有直接關聯,但是它們通常在執行一些用戶關心的操作(例如,在後台播放音樂或從網路下載數據)。因此,除非內存不足以維持所有前台進程和可見進程同時運行,否則系統會讓服務進程保持運行狀態。
4)後台進程(Background process)
後台進程對用戶體驗沒有直接影響,系統可能隨時終止它們,以回收內存供前台進程、可見進程或服務進程使用。 通常會有很多後台進程在運行,因此它們會保存在 LRU 列表中,以確保包含用戶最近查看的 Activity 的進程最後一個被終止。如果某個 Activity 正確實現了生命周期方法,並保存了其當前狀態,則終止其進程不會對用戶體驗產生明顯影響,因為當用戶導航回該 Activity 時,Activity 會恢復其所有可見狀態。
5)空進程(Empty process)
不含任何活動應用組件的進程。保留這種進程的的唯一目的是用作緩存,以縮短下次在其中運行組件所需的啟動時間。 為使總體系統資源在進程緩存和底層內核緩存之間保持平衡,系統往往會終止這些進程。
通常,前面三種進程不會被殺死。
2. 回收收益
當Android系統開始殺死LRU緩存中的進程時,系統會判斷每個進程殺死後帶來的回收收益。因為Android總是傾向於殺死一個能回收更多內存的進程,從而可以殺死更少的進程,來獲取更多的內存。殺死的進程越少,對用戶體驗的影響就越小。
為什麼App要符合內存管理機制?
在Android系統中,符合內存管理機制的App,對Android系統和App來說,是一個雙贏的過程。如何每一個App都遵循這個規則,那麼Android系統會更加流暢,也會帶來更好的用戶體驗,App也可以更長時間的駐留在內存中。
如果真的需要很多內存,可以採用多進程的方式。
如何編寫符合Android內存管理機制的App?
一個遵循Android內存管理機制的App應該具有以下幾個特點:
1)更少的佔用內存;
2)在合適的時候,合理的釋放系統資源。
3)在系統內存緊張的情況下,能釋放掉大部分不重要的資源,來為Android系統提供可用的內存。
4)能夠很合理的在特殊生命周期中,保存或者還原重要數據,以至於系統能夠正確的重要恢復該應用。
因此,在開發過程中要做到:
- 避免創建不必要的對象。
- 在合適的生命周期中,合理的管理資源。
- 在系統內存不足時,主動釋放更多的資源。
開發時,應該如何注意App的內存管理呢?
1)減少內存資源佔用
比如,使用StringBuffer,int等更少內存佔用的數據結構。
2)內存溢出
主要是Bitmap。解決辦法是:減少每個對象佔用的內存,如圖片壓縮等;申請大內存。
3)內存泄露
內存泄露是指本來該被GC回收後還給系統的內存,並沒有被GC回收。多數是因為不合理的對象引用造成的。
解決這種問題:1、通過各種內存分析工具,比如MAT,分析運行時的內存映像文件,找出造成內存泄露的代碼,並修改。2、適當的使用WeakReference。
推薦閱讀:
※Android App Shortcuts
※探究android:largeHeap
※返回、向上和關閉
※Android NDK 入門與實踐
TAG:Android |