偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Android 開(kāi)發(fā),跳不過(guò)的內(nèi)存管理

企業(yè)動(dòng)態(tài)
在 Android 系統(tǒng)中,當(dāng)運(yùn)行的 App 被移動(dòng)到后臺(tái)的之后,Android 為了保證下次啟動(dòng)的速度,會(huì)將它移入 Cached 的狀態(tài),這個(gè)時(shí)候?qū)嶋H上,該 App 的進(jìn)程依然存在,但是對(duì)應(yīng)的組件是否存在,就不一定了。而既然該 App 的進(jìn)程還存活著,下次啟動(dòng)的速度就會(huì)很快,這就是常說(shuō)的熱啟動(dòng)。

[[195537]]

 一、前言

在 Android 系統(tǒng)中,當(dāng)運(yùn)行的 App 被移動(dòng)到后臺(tái)的之后,Android 為了保證下次啟動(dòng)的速度,會(huì)將它移入 Cached 的狀態(tài),這個(gè)時(shí)候?qū)嶋H上,該 App 的進(jìn)程依然存在,但是對(duì)應(yīng)的組件是否存在,就不一定了。而既然該 App 的進(jìn)程還存活著,下次啟動(dòng)的速度就會(huì)很快,這就是常說(shuō)的熱啟動(dòng)。

但是這些被退出到后臺(tái)的 App ,也并不是完全安全不會(huì)被清理掉的,他們可能只是沒(méi)有持有任何的組件,并且是不占用 CPU 資源的,但是它依然會(huì)占據(jù)內(nèi)存空間。而當(dāng)系統(tǒng)認(rèn)為內(nèi)存不足的時(shí)候,就會(huì)按照優(yōu)先級(jí)清理掉一些優(yōu)先級(jí)不那么高的進(jìn)程,來(lái)回收一些內(nèi)存空間,供新啟動(dòng)的程序使用,這就是 LowMemoryKiller 的策略。

那么,為了讓我們的 App 在后臺(tái)盡可能活的久一點(diǎn),無(wú)非就是將內(nèi)存降低,從而使得優(yōu)先級(jí)提高,而實(shí)現(xiàn)不被系統(tǒng)回收的功能(這是一個(gè)常規(guī)的優(yōu)化方案,而非保活方案)。那么,如果我們能明確當(dāng)前 App 處于什么狀態(tài),就能在此時(shí)機(jī),釋放一些不需要持有的內(nèi)存資源,來(lái)達(dá)到我們的目的。

這個(gè)時(shí)候,就需要用到 onTrimMemory() 這個(gè)回調(diào)方法了。

二、什么是 onTrimMemory

1、onTrimMemory 的作用

前面提到,我們可以通過(guò)實(shí)現(xiàn) onTrimMemory() 方法,來(lái)完成對(duì)當(dāng)前 App 在內(nèi)存中的優(yōu)先級(jí)的簡(jiǎn)單管理。

而 onTrimMemory() 回調(diào)方法,是 Android Level 14(Android 4.0) 之后提供的一個(gè) API,它主要的作用是提醒開(kāi)發(fā)者,在系統(tǒng)內(nèi)存不足的時(shí)候,應(yīng)該通過(guò)釋放部分不重要的內(nèi)存資源,從而避免被 Android 系統(tǒng)服務(wù)殺掉。

可以看到,onTrimMemory() 本質(zhì)上是一種告知 App 處于系統(tǒng)內(nèi)存回收的不同階段的時(shí)機(jī),應(yīng)該在這些時(shí)機(jī),合理對(duì)自身持有的內(nèi)存進(jìn)行釋放,以避免被系統(tǒng)直接殺掉,從而讓保證下次用戶(hù)啟動(dòng) App 時(shí)候的速度。

onTrimMemory() 的完整方法簽名如下:

  1. public void onTrimMemory(int level

可以看到,它實(shí)際上,會(huì)有一個(gè) level 參數(shù)來(lái)標(biāo)記當(dāng)前的 App 在內(nèi)存中的級(jí)別,也就意味著 onTrimMemory() 方法,可能會(huì)被多次調(diào)用到。

2、 onTrimMemory 回傳的參數(shù)的意義

既然 onTrimMemory() 方法會(huì)傳遞一個(gè) level 參數(shù),那么就先來(lái)看看,各種 level 參數(shù)所代表的含義。

  • TRIM_MEMORY_UI_HIDDEN:App 的所有 UI 界面被隱藏,最常見(jiàn)的就是 App 被 home 鍵或者 back 鍵,置換到后臺(tái)了。
  • TRIM_MEMORY_RUNNING_MODERATE:表示 App 正常運(yùn)行,并且不會(huì)被殺掉,但是目前手機(jī)內(nèi)存已經(jīng)有點(diǎn)低了,系統(tǒng)可能會(huì)根據(jù) LRU List 來(lái)開(kāi)始?xì)⑦M(jìn)程。
  • TRIM_MEMORY_RUNNING_LOW:表示 App正常運(yùn)行,并且不會(huì)被殺掉。但是目前手機(jī)內(nèi)存已經(jīng)非常低了。
  • TRIM_MEMORY_RUNNING_CRITICAL:表示 App 正在正常運(yùn)行,但是系統(tǒng)已經(jīng)開(kāi)始根據(jù) LRU List 的緩存規(guī)則殺掉了一部分緩存的進(jìn)程。這個(gè)時(shí)候應(yīng)該盡可能的釋放掉不需要的內(nèi)存資源,否者系統(tǒng)可能會(huì)繼續(xù)殺掉其他緩存中的進(jìn)程。
  • TRIM_MEMORY_BACKGROUND:表示 App 退出到后臺(tái),并且已經(jīng)處于 LRU List 比較靠后的位置,暫時(shí)前面還有一些其他的 App 進(jìn)程,暫時(shí)不用擔(dān)心被殺掉。
  • TRIM_MENORY_MODERATE:表示 App 退出到后臺(tái),并且已經(jīng)處于 LRU List 中間的位置,如果手機(jī)內(nèi)存仍然不夠的話(huà),還是有被殺掉的風(fēng)險(xiǎn)的。
  • TRIM_MEMORY_COMPLETE:表示 App 退出到后臺(tái),并且已經(jīng)處于 LRU List 比較考靠前的位置,并且手機(jī)內(nèi)存已經(jīng)極低,隨時(shí)都有可能被系統(tǒng)殺掉。

其實(shí)從 level 值的取名來(lái)看,大致可以分為三類(lèi):

  1. UI 置于后臺(tái):TRIM_MEMORY_UI_HIDDEN 。
  2. App 正在前臺(tái)運(yùn)行時(shí)候的狀態(tài):TRIM_MEMORY_RUNNING_Xxx
  3. App 被置于后臺(tái),在 Cached 狀態(tài)下的回調(diào):TRIM_MEMORY_Xxx

這三類(lèi)中,通常我們只需要關(guān)心 App 被置于 Cached 狀態(tài)下的情況,因?yàn)橄到y(tǒng)是不會(huì)殺掉一個(gè)正在前臺(tái)運(yùn)行的 App 的(但可能會(huì)觸發(fā) OOM),但是如果該 App 有一些后臺(tái)服務(wù)正在運(yùn)行,這個(gè)服務(wù)也是有被殺的風(fēng)險(xiǎn)的。

而在 Cached 狀態(tài)下的時(shí)候,當(dāng)收到 TRIM_MEMORY_Xxx 的回調(diào),就需要注意了,這些只是標(biāo)記了當(dāng)前 App 處于 LRU List 的位置,也就是說(shuō),如果回收了靠前的 App 進(jìn)程之后,依然達(dá)不到內(nèi)存使用的要求,可能會(huì)進(jìn)一步去殺進(jìn)程,也就是說(shuō),極端情況下,可能從 TRIM_MEMORY_BACKGROUND 到 TRIM_MEMORY_COMPLETE 是瞬間完成的事情,所以我們需要慎重處理它們,盡量對(duì)這三個(gè)狀態(tài)都進(jìn)行判斷,然后做統(tǒng)一的回收內(nèi)存資源的處理。

3、哪些組件可以監(jiān)聽(tīng) onTrimMemory

既然說(shuō)到了 onTrimMemory() 回掉,看樣子它是和 App 相關(guān)的,所以最少在 Application 中,應(yīng)該是可以對(duì)其進(jìn)行重寫(xiě)來(lái)監(jiān)聽(tīng)回調(diào)的。但是除了 Application,其他的一些組件中,也是可以監(jiān)聽(tīng)它的。

這些可以監(jiān)聽(tīng) onTrimMemory 的組件有:

  • Application
  • Activity
  • Fragment
  • Service
  • ContentProvider

4、自定義 onTrimMemroy 監(jiān)聽(tīng)

除了前面提到的系統(tǒng)默認(rèn)可以監(jiān)聽(tīng) onTrimMemory() 的組件之外,我們還可以自定義 onTrimMemory 的監(jiān)聽(tīng)。

自定義起來(lái)也非常的簡(jiǎn)單,只需要實(shí)現(xiàn) ComponentCallbacks2 接口,然后調(diào)用 Application.registerComponentCallbacks() 方法注冊(cè)即可。

除了 registerComponentCallbacks() 方法進(jìn)行注冊(cè)監(jiān)聽(tīng)之外,如果不使用了的話(huà),還可以使用 unregisterComponentCallbacks() 進(jìn)行解注。

那么這里是如何實(shí)現(xiàn)的呢?讓我們來(lái)看看 Application 的對(duì)應(yīng)源碼。

可以看到,它實(shí)際上是通過(guò)一個(gè) mComponentCallbacks 的列表進(jìn)行維護(hù)的。

而在 onTrimMemory() 的時(shí)候,又從 mComponentCallbacks 中獲取到所有的 callbacks 對(duì)象,進(jìn)行消息的分發(fā)。

通過(guò)這種方式實(shí)現(xiàn)了對(duì) onTrimMemory() 的自定義監(jiān)聽(tīng)。

而 onTrimMemory() 方法同時(shí)被標(biāo)記為 @CallSuper,也就嚴(yán)格要求了重寫(xiě)它的子類(lèi),必須調(diào)用父類(lèi)中的 onTrimMemory() 方法,從而保證了消息的分發(fā)不會(huì)缺失。

5、onLowMemory()

onTrimMemory() 既然是 Android 4.0 才新增加的 Api,那么對(duì)于低版本的設(shè)備而言,可以監(jiān)聽(tīng) onLowMemory() 方法,它大概可以等同于 level 級(jí)別為 TRIM_MEMORY_COMPLETE 的回調(diào)。

當(dāng)然,ComponentCallbacks2 接口繼承的 ComponentCallback 接口,也是需要實(shí)現(xiàn) onLowMemory() 方法的。

三、onTrimMemory 的一些思考?

1、為什么需要 onTrimMemory()

Android 系統(tǒng)會(huì)在自身內(nèi)存不足的情況下,清理掉一些不重要的進(jìn)程來(lái)釋放內(nèi)存資源,以供優(yōu)先級(jí)更高的進(jìn)程使用。而這個(gè)順序,主要是按照 LRU List 中的優(yōu)先級(jí)來(lái)清理的,但是它也同時(shí)會(huì)考慮清理掉哪些占用內(nèi)存較高的進(jìn)程來(lái)讓系統(tǒng)更快的釋放跟多的內(nèi)存。

所以,盡可能的讓 App 在系統(tǒng)內(nèi),占用足夠小的內(nèi)存資源,就可以降低被殺的概率,從而下次啟動(dòng)的時(shí)候走熱啟動(dòng)的方式,提升用戶(hù)的體驗(yàn)。

換一個(gè)角度來(lái)說(shuō),讓 App 占用較小的內(nèi)存,也可以?xún)?yōu)化系統(tǒng)的速度,畢竟系統(tǒng)清理進(jìn)程釋放內(nèi)存的過(guò)程,也是需要占用 CPU 資源的。在大環(huán)境下,也是有意義的。

所以,在 onTrimMemory() 的時(shí)機(jī),對(duì)當(dāng)前 App 的內(nèi)存進(jìn)行釋放優(yōu)化,就尤為重要了。

2、在 onTrimMemory 回調(diào)中,應(yīng)該釋放哪些資源

在 onTrimMemory() 回調(diào)中,應(yīng)該在一些狀態(tài)下清理掉不重要的內(nèi)存資源。在不考慮內(nèi)存泄露的情況下,有一些資源是我們主動(dòng)緩存起來(lái),以便我們?cè)谑褂玫倪^(guò)程中可以快速獲取,而這部分資源就是我們清理的重點(diǎn)。

對(duì)于這些緩存,只要是讀進(jìn)內(nèi)存內(nèi)的都算,例如最常見(jiàn)的圖片緩存、文件緩存等。拿圖片緩存來(lái)說(shuō),市場(chǎng)上,常規(guī)的圖片加載庫(kù),一般而言都是三級(jí)緩存,所以在內(nèi)存吃緊的時(shí)候,我們就應(yīng)該優(yōu)先清理掉這部分圖片緩存,畢竟圖片是吃?xún)?nèi)存大戶(hù),而且再次回來(lái)的時(shí)候,雖然內(nèi)存中的資源被回收掉了,我們依然可以從磁盤(pán)或者網(wǎng)絡(luò)上恢復(fù)它。

除了資源緩存之外,還有一些頁(yè)面相關(guān)的資源,也是占據(jù)內(nèi)存的,可以考慮清理掉 Activity Task 中,多余的 Activity,只保留 Root Activity 。

其實(shí)核心思想,就是根據(jù) onTrimMemory() 回調(diào)的一些信息,來(lái)釋放我們持有的可被恢復(fù),不那么重要的內(nèi)存資源,以提高系統(tǒng)性能,已經(jīng)保證當(dāng)前 App 的進(jìn)程不那么容易被系統(tǒng)回收。

【本文為51CTO專(zhuān)欄作者“張旸”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)微信公眾號(hào)聯(lián)系作者獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專(zhuān)欄
相關(guān)推薦

2014-07-31 10:48:09

Android內(nèi)存管理OOM

2014-01-02 15:08:35

手游渠道IP

2017-09-11 14:48:47

5G毫米波寬帶

2011-07-21 14:42:45

iOS UIViewCont 內(nèi)存

2014-07-21 14:40:43

Android內(nèi)存

2014-07-28 15:01:56

Android內(nèi)存

2015-09-16 15:32:37

Android Tra內(nèi)存管理

2011-07-26 15:14:24

蘋(píng)果 Cocoa 內(nèi)存

2013-05-23 13:57:24

2014-06-10 15:28:04

2010-07-29 10:16:17

Linux內(nèi)核Linux內(nèi)存

2013-09-16 16:56:09

AndroidBitmap內(nèi)存優(yōu)化

2014-10-30 10:53:22

Android內(nèi)存優(yōu)化

2015-07-16 15:16:41

內(nèi)存泄露解決辦法

2017-02-09 21:24:22

iOS內(nèi)存管理

2015-03-13 09:30:23

iOS內(nèi)存管理

2011-07-21 15:40:24

iPhone 內(nèi)存管理 對(duì)象

2011-08-22 11:07:16

IOS 開(kāi)發(fā)多核內(nèi)存

2018-07-23 09:26:08

iOS內(nèi)存優(yōu)化

2013-10-11 17:32:18

Linux運(yùn)維內(nèi)存管理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)