標籤:android 記憶體 效能最佳化
大家如果喜歡我的部落格,請關注一下我的微博,請點擊這裡(http://weibo.com/kifile),謝謝
轉載請標明出處(http://blog.csdn.net/kifile),再次感謝
原文地址:http://developer.android.com/training/articles/memory.html
在接下來的一段時間裡,我會每天翻譯一部分關於效能提升的Android官方文檔給大家
建議大家在看本文之前先去我的部落格看看
[Android 效能最佳化系列]記憶體之基礎篇--Android如何管理記憶體
下面是本次的本文:
################
應用應該如何管理記憶體
在軟體開發的各個階段,你都應該時候注意你的RAM消耗(即便是在括軟體的設計階段)。這裡有很多種途徑,通過使用它們可以協助你設計和寫出更有效率的代碼,
你應該在設計和實現應用的時候採用以下的這些技術來讓降低應用的記憶體消耗。
儘可能少的使用服務
如果你的應用需要使用服務來進行後台操作,那麼儘可能讓他在的確需要工作的時候才進行工作。另外請確保當你的工作完成之後結束掉你的服務。
當你開啟一個服務的時候,系統會在服務啟動並執行時候保留它的進程,這會讓這個進行變得非常龐大,因為服務所消耗的資源不能被其他應用使用或者回收。這就會導致儲存在LRU緩衝中的進程數量減少,使得切換應用的時候效率降低。當後台有足夠多的服務正在啟動並執行時候,他甚至可能導致整個系統因為記憶體緊張而崩潰掉。
管理你的服務最簡單的方法是使用一個IntentService,他會在他處理完事件之後自行關閉掉服務,詳情請參看使用前台服務。
當不需要的時候還讓服務一直在後台運行是記憶體管理中最不應該犯的錯之一。因此不要貪心的讓自己的服務一直在後台運行,這不僅會導致你應用的效能變低,使用者也有可能發現應用的這種行為並且卸載他。
當使用者介面隱藏起來的時候,釋放掉記憶體資源
當使用者切換到其他應用,你的ui介面不可見的時候,你就應該釋放掉那些被自己介面使用的資源。在這個時候釋放掉ui資源能夠顯著提升系統存放緩衝進程的數目,這可以極大的提升使用者體驗。
當你應用中的所有進程的介面對於使用者而言都不可見的時候,會觸發onTrimMemory()的回調介面,帶著一個TRIM_MEMORY_UI_HIDDEN參數。這個介面同OnStop()的回調介面的不同在於 OnStop()介面會在應用跳轉的時候被調用,而onTrimMemory介面只有在所有介面都不可見的情況下被調用,儘管你需要實現onStop()方法來釋放掉Activity資源,例如網路訪問或者登出掉廣播接收器,但這還不夠,你不應該在onTrimMemory之前就釋放掉你的ui資源。這能夠保證使用者通過返回鍵返回到你的應用中,你的ui資源同樣存在,而且能夠快速的顯示出來。
當記憶體不足時釋放掉一些記憶體
在你的應用的生命週期中,onTrimMemory()介面同樣會在當整個裝置的記憶體變得很低的時候被調用。你應該根據從onTrimMemory()中傳來的記憶體等級,選擇性的釋放掉你資源
TRIM_MEMORY_RUNNING_MODERATE
你的應用正在運行,不可被殺死,但是目前裝置剩餘記憶體很少,系統需要從LRU緩衝中殺死掉一些進程
TRIM_MEMORY_RUNNING_LOW
你的應用正在運行,不可被殺死,但是目前裝置剩餘記憶體不足臨界值,因此你需要釋放掉不是用的記憶體來提升系統運行效率
TRIM_MEMORY_RUNNING_CRITICAL
你的應用正在運行,但是系統已經準備殺死大多數LRU中的進程,因此你應該釋放掉那些不是很關鍵的資源。如果系統不能通過回收得到足夠的RAM,那麼他會清空所有LRU緩衝,並且開始殺死那些希望保留的進程,例如擁有一個正在運行後台服務的進程。
同樣的,當你的應用正在處於緩衝中的時候,你可能會受到以下幾個onTrimMemory()等級
TRIM_MEMORY_BACKGROUND
系統正在運行在低記憶體狀態,而你的進程處在LRU列表的開始部分。因此儘管你的應用進程不太可能被殺死,但是系統已經轉杯開始殺死LRU中的進程。你應該釋放掉那些容易被還原的資源,來確保你仍然在列表中,並且在使用者返回到應用的時候能夠快速的進行切換
TRIM_MEMORY_MODERATE
系統正在運行在低記憶體階段,你的進程處於LRU列表的中部。加入系統無法獲得足夠的記憶體資源,你的應用將會被殺死
TRIM_MEMORY_COMPLETE
系統正在運行在低記憶體階段,你的進程將會是最開始被系統殺死的進程之一,你應該釋放掉所有與你的應用狀態無關的資源。
雖然由於onTrimMemory()介面直到API14的時候才被加入,你還是可以使用onLowMemory介面來作為老版本的回調,他可以同onTrimMemory()中TRIM_MEMORY_COMPLETE的等級一樣。
注意:當系統開始殺死在LRU緩衝中的進程時,儘管他是從下至上開始的,但是他也會考慮優先殺死那些記憶體消耗比較大的,以回收更多的系統資源。因此,如果你的應用的記憶體儘可能低,你就可能被始終保留在記憶體中,能夠很快切換回來
判斷你應該擁有多少記憶體
正如之前所提到的,每一個Android裝置都會根據自身RAM大小的不同來嚮應用提供不同大小的堆限制。你可以通過getMemoryClass()來得到應用可能擁有的堆的大小。加入你的應用當記憶體不足的時候卻分配更多的記憶體,那麼就會造成OOM
在一種非常特殊的情況加,你可以通過設定manifest檔案中<application>標籤裡的largeHeap的屬性為true。如果你這麼做,那麼你可以通過getLargeMemoryClass()來擷取你個比較大的堆的評估值。
儘管如此,最好只有那些真正需要更多記憶體空間的應用才請求一個更大的堆空間,例如一個大型的影像編輯應用。記住不要因為你記憶體溢出就去申請一個大型堆,你需要知道只有你明白你的記憶體被分配到哪兒了,為什麼他一直被保留著。當你確信你的應用需要一個大型堆的時候,你應該避免隨意浪費他,使用額外的記憶體會極大的影響使用者的體驗,因為記憶體回收會消耗更多的事件,並且系統的效率會在應用程式切換或者其他的操作上變得更慢
此外,一個大型堆的大小在不同的裝置上不一樣,當運行在某些擁有限制記憶體的裝置上時,大型堆的大小可能同普通堆得大小一模一樣。因此即使你使用了大型堆,你也應該通過getMemoryClass()來檢查真正的堆的尺寸,以確保不過超出限制。
[Android 效能最佳化系列]記憶體之提升篇--應用應該如何管理記憶體