[Android 性能優化系列]內存之提升篇--應用應該如何管理內存

大家如果喜歡我的博客,請關注一下我的微博,請點擊這裏(http://weibo.com/kifile),謝謝

轉載請標明出處(http://blog.csdn.net/kifile),再次感謝


原文地址:http://developer.android.com/training/articles/memory.html

在接下來的一段時間裏,我會每天翻譯一部分關於性能提升的Android官方文檔給大家

建議大家在看本文之前先去我的博客看看

[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()來檢查真正的堆的尺寸,以確保不過超出限制。

發佈了28 篇原創文章 · 獲贊 7 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章