我知道,對于很多人而言,尤其是那些有強迫癥者,這是個然并卵的命題,但是在我們周圍,還有很多這樣的智能手機用戶:怎么這個手機3G內(nèi)存,空閑的也只有600MB呢?以前那個2G內(nèi)存的手機都有800MB的空閑,我要一鍵清理內(nèi)存,我要定時清理內(nèi)存……
清理與加速,是手機助手們吹噓的主要功能
像我們這些在Windows陪伴下成長起來的玩家,“內(nèi)存不足”是留存在心底揮之不去的陰影,即便到了今天,到了Android系統(tǒng),這個陰影依舊。實際上Android有著與Windows完全不一樣的內(nèi)存管理機制,Windows上的那一套,在這兒并不是行之有效的。
Android中可用內(nèi)存只是個沒意義的數(shù)字
在Windows中,可用內(nèi)存是越多越好,但在Android中,完全不必在意這個數(shù)據(jù)。在下圖中,有著3GB內(nèi)存的某手機,實際可用內(nèi)存只有81MB了,你可千萬別說這個系統(tǒng)好垃圾,只能顯得自己的無知。
一加手機X的內(nèi)存使用狀況(內(nèi)存3GB可用的只有81MB了)
Windows中只有需要用到內(nèi)存時才會為程序分配內(nèi)存,一旦這個程序被關(guān)閉,分配的內(nèi)存也就釋放出來成為新的可用內(nèi)存。然而絕大多數(shù)Android應(yīng)用都沒有退出的菜單設(shè)計,這些運行過的應(yīng)用無非是從前臺轉(zhuǎn)入到后臺,大多數(shù)依舊保留在內(nèi)存中并不會也不需要主動釋放,這樣下次再運行該應(yīng)用時,可以更快的啟動。
無論手機的物理內(nèi)存有多大,Android都能將其充分利用,將需要用到(包括之前用過的)的數(shù)據(jù)從硬盤讀入到內(nèi)存,利用內(nèi)存的高速保證系統(tǒng)的數(shù)據(jù)訪問性能,也就是說,可用內(nèi)存越小,內(nèi)存的利用率就更高,其中的數(shù)據(jù)就越多,數(shù)據(jù)訪問的命中率就越高,系統(tǒng)也就越快。如果還有人和你說手機用不了4GB這么的大內(nèi)存,那只是廠商的噱頭而已,你完全可以鄙視再教育之。
你可能會問,當(dāng)打開的應(yīng)用越來越多,占用的內(nèi)存總會爆滿的,那怎么辦呢?
該出手時就出手,Android有著優(yōu)秀的內(nèi)存回收機制
在上面舉例中,3GB內(nèi)存的手機只有81MB的可用內(nèi)存了,如果此時打開需要256MB內(nèi)存的“騰訊視頻”,會提示“內(nèi)存不足”嗎?答案是不會的。
當(dāng)內(nèi)存不足時,內(nèi)存回收機制就開始起作用了
實際上,作為Android的開發(fā)語言Java沒有提供任何操作來釋放內(nèi)存(這也是與IOS很大的不同點),是通過系統(tǒng)的內(nèi)存回收機制來進行管理。Android使用了一個名為Low Memory Killer(LMK)的機制來管理內(nèi)存,當(dāng)內(nèi)存出現(xiàn)不足時,LMK就開始揮舞屠刀殺掉一些進程,那么問題來了,殺誰?
說到這兒,必須多費點筆墨。Android會對進程的重要性進行評估,以oom_adj來表示,oom_adj的值越小,則重要性越高,oom_adj的值越大,該進程被系統(tǒng)選中殺掉的可能性越高,當(dāng)oom_adj值為0,這意味著它永遠不會被系統(tǒng)終止。
Android有一套自己獨特的進程管理,比如可以設(shè)定“當(dāng)內(nèi)存小于22M時,結(jié)束oom_adj大于14的進程”這樣的策略,可以看到oom_adj非常重要,關(guān)乎進程的死生命運。
Android默認的進程管理策略
像上表描述的那樣,在默認策略中,當(dāng)內(nèi)存低于24MB(6144*4K)時,LMK就會殺掉所有oom_adj為15的進程(即空進程),這個警戒值可以人為修改,一般情況下也沒必要去改變它。為了更好的評估進程的重要性,Android將進程分為六類,如下所述:
前臺進程(foreground):oom_adj=0,指正在當(dāng)前屏幕上顯示的進程和一些系統(tǒng)進程,一旦你回到主界面 或切換到其它程序,當(dāng)前進程變?yōu)殡[藏進程,前臺進程是不會殺掉的;
可見進程(visible):oom_adj=1,可見進程雖然不在前臺,但依然可見,如widget、輸入法等,這部分進程也非常重要,基本上不可能被殺掉;
次要服務(wù)(secondary server):oom_adj=2,目前正在運行的一些服務(wù),如下載、播放音樂,它們雖然屬于次要服務(wù),但與系統(tǒng)息息相關(guān),一般也不會被殺掉;
隱藏進程(hidden):oom_adj=7,這個很容易理解,當(dāng)應(yīng)用從前臺轉(zhuǎn)入到后臺后,也就成為隱藏進程了,通常一鍵清理內(nèi)存就是清掉這些隱藏進程;
內(nèi)容提供者(content provider):oom_adj=14,沒有程序?qū)嶓w,只提供內(nèi)容供別的程序去用的,比如日歷供應(yīng)節(jié)點,顯然這類進程最有可能被先殺掉;
空進程(empty):oom_adj=15,有些程序在程序退出后,依然會在進程中駐留一個空進程,這個進程里沒有任何數(shù)據(jù)在運行,作用往往是提高該程序下次的啟動速度或者記錄程序的一些歷史信息,這類進程無疑是要最先被殺掉的。
Android的內(nèi)存管理機制非常適合嵌入式系統(tǒng),能充分發(fā)揮出硬件的潛力,當(dāng)內(nèi)存越大,它的優(yōu)勢就越明顯。
回到要討論的話題,Android手機需要清內(nèi)存嗎?需要嗎?需要嗎?需要嗎?結(jié)論是再明顯不過:不需要!其實這個結(jié)論也適用iPhone手機,IOS在內(nèi)存管理方面更為激進。
我們完全不用糾結(jié)Android手機上的可用內(nèi)存大小,也不需要去一鍵清理內(nèi)存,有時可能還會適得其反,尤其是在手機內(nèi)存2GB起步3GB成主流的今天,我們會很享受Android的內(nèi)存管理機制。目前硬件規(guī)格的Android手機系統(tǒng)流暢度上都有著很好的表現(xiàn),基本上能與IOS叫板,在Android 5.1.1以上版本中如絲般順滑都是可以期待的,至于為什么會“越用越卡”,這個問題就有點復(fù)雜,下次再討論吧。