慎用內存釋放軟件,剖析1Gram手機的內存原理
經常看見有人推薦一鍵釋放內存的內存管理軟件,或者說自己的ROM精簡後可用內存有500+甚至600+……我個人是很不理解了……
首先,從內存的原理說起。這個說起來比較長篇,舉個簡單的例子來說明:你去圖書館看書,書都在書架上,你會有一張桌子。對於電腦/手機來說,書架就是硬盤或者內置的ROM/SD卡,桌子就是內存,你就是CPU,書就是數據(程序本身也是數據,隻是一種比較特殊的數據而已)。你看書的時候是從書架上把書取出來,放在桌子上看;CPU需要數據的時候,是從硬盤/SD卡把數據載入到內存之後,進行處理。
那麼大內存有什麼好處呢?用圖書館的例子繼續說明:如果你的桌子很小,剛看了幾本書,你的桌子上已經擺滿了,但現在你需要參考幾本書架上的書,你隻能把桌子上的若幹本書放回書架(假設書籍不能堆疊著放),然後到書架去拿新書。但事實上,很有可能你放回書架的書呆會還需要繼續看,你不得不在看完這幾本書後,再把幾本暫時不看的書放回書架,把剛才放回書架的書又拿出來……最後的結果是你一整天的時間,有大部分在不停的取書-放書-取書這個循環中浪費掉。而如果桌子足夠大的話,就沒有這個問題,你完全可以把整一個書架的書都放到桌子上,需要哪本就看哪本。
對於1G ram的手機來講,經常使用一鍵清理軟件,把可用內存保持在500+,就相當於你本來有一張大桌子,但為了看著桌子幹淨整潔,所以當桌子上的書超過一定數量之後,你就把除了手上在看的那本書以外,全部都放回書架上……這個真的很沒有必要,也很浪費資源。
Android本身其實有很不錯的內存回收機製,通常叫minfree:
1、Android自身並沒有所謂的關閉進程的說法 每當我們要退出一個進程回到桌麵/打開另一個程序的時候我們隻能按"返回鍵". 而當我們按下"返回鍵"後,該進程並沒有真正的關閉,仍然保存在內存中. 這樣在下次調用的時候可以更快的打開該程序
2、要想真正的關閉一個已打開的進程,除了用第三方軟件(例如advanced task manager)外,還有一個,那就是當Android係統認為當時已經沒有足夠的內存來運行新的進程,需要關閉一些雖然已經開著,但是沒有用了(具體怎樣一個進程才會被Android係統認為是"沒有用"下麵就要討論到)的進程
3、ActivityManagerService.java記錄著每一個進程的優先級. 一個進程的oom_adj值也就代表了它的優先級. oom_adj值越高代表該進程優先級越低. 一個正在使用的進程的oom_adj值為0,一旦我們按下返回鍵,這個進程就會得到一個更高的oom_adj值(更低的優先級). 具體多少取決於該進程在LRU(last recently used) list的位置.(未證實)
具體的細節保存在Android源文件drivers/misc/lowmemorykiller.c裏
4、Android將進程分為6個等級,它們按優先級順序由高到低依次是:
A、foreground app:前台程序,但事實上除了你正在運行的前台程序,還包括一些係統應用,例如啟動器(或者叫桌麵)、撥號程序、短信、聯係人信息、USB服務等,對A4來說,還有Blur、溫度監控、Moto門戶、指紋等。
B、visible app:“可見”程序,一般來說是輸入法,對於A4來說,還有通話錄音(國行)和進程管理。
C、secondary service:服務程序,不過不包括係統服務。這些一般是第三方軟件的後台服務了,在我的手機上,Go天氣、七鍵開關、同花順、PC助手之類的。
D、hidden app:前台(不包括係統應用),如果按下“home”回到桌麵或者通過長按“home”以及程序本身提供的切換、調用功能切換到其他程序的時候,這個程序就變成hidden app。
E、content provider:直譯就是內容提供者了。事實上這是沒有客戶端的secondary service,這個有點不好解釋,舉例來說明吧,A4有一個Blur相關的應用叫“切換小部件”,就是一個contend provider,如果你在桌麵上通過添加“Moto小部件”增加Wifi/GPS/3G/藍牙中的一個或者多個切換的桌麵插件,它就有了客戶端,變成了secondary service,如果你再把所有的切換插件從桌麵刪除,它就沒有客戶端了,又變回content provider。
F、empty app:空應用。這個空進程有兩種,第一種是你運行的程序,通過程序提供的退出操作退出程序,或者主界麵按返回鍵退出到桌麵的程序,並不會馬上從內存釋放掉這個程序的數據,android會把程序數據保留在內存裏,這樣你下次調用這個程序的時候,就不需要從ROM或者程序存儲裏麵重新讀取程序了。第二種,如果可用內存大於minfree裏麵的empty app設置,android會在空閑的時候,把沒有運行過的程序數據讀進內存。沒錯,就是你開機之後一直都沒有運行過的程序!
當然不會是所有安裝了的程序都會預加載,從網上的資料觀察來看,似乎在桌麵上有快捷方式的,或者用的比較多的應用,Android都會預加載進內存。對於一般的釋放內存軟件來說,釋放內存會把D、E、F三種程序結束掉,在A4上很搞笑的一件事情是,如果是未經修改(精簡自帶應用不算修改)的ROM,係統空閑的時候會自動讀取存儲,把結束掉的程序重新載入到內存(因為剛剛運行過,預載優先級會高一點),直到所有符合預載規則的程序都已經載入內存,或者可用內存低於minfree裏麵empty app(A4默認是)的設置值為止……也就是說:內存釋放軟件不但做的是無用功,而且增加了係統讀取程序數據的操作。
追求高可用內存的朋友,估計很大一部分是從256M/384M內存的手機過來,又或者習慣了Windows的內存管理方式的,但對於Android來說,其實隻要可用內存大於你馬上要運行的程序所需要的內存,不需要在運行程序的時候,係統要按照預設的規則結束掉一部分程序釋放出足夠的可用內存就OK了。也就是說,隻要minfree裏麵empty app的設置值比你通常要運行的最占用內存的程序所需要的內存大一點就可以了。
按照標準Android應用設計的程序,處於第四級、第五級的時候也不會消耗CPU資源的,而常見的內存釋放軟件也不會強製結束前三級的程序來釋放內存,所以如果某個應用後台會耗電的話,隻能說這個應用的開發者在設計的時候沒有很好的理解Android應用的架構,或者出於其他原因,使用了service的方式運行,又或者在service沒有client的時候還在進行一些操作。對於這樣的程序,用任務管理軟件單獨殺掉應用程序的進程其實更好一點。
最後更新:2017-04-02 16:48:17