標籤:gen 技術 lan exp androi tle shell命令 shel text
本文轉載自:http://www.cnblogs.com/wytiger/p/5744752.html
熟悉Android系統的童鞋都知道,系統出於體驗和效能上的考慮,app在退到後台時系統並不會真正的kill掉這個進程,而是將其緩衝起來。開啟的應用越多,後台緩衝的進程也越多。在系統記憶體不足的情況下,系統開始依據自身的一套進程回收機制來判斷要kill掉哪些進程,以騰出記憶體來供給需要的app, 這套殺進程回收記憶體的機制就叫 Low Memory Killer ,它是基於Linux核心的 OOM Killer機制誕生。(更多關於Low Memory Killer請參考: Android Low Memory Killer)
瞭解完 Low Memory Killer,再科普一下oom_adj。什麼是oom_adj?它是linux核心分配給每個系統進程的一個值,代表進程的優先順序,進程回收機制就是根據這個優先順序來決定是否進行回收。對於oom_adj的作用,你只需要記住以下幾點即可:
- 進程的oom_adj越大,表示此進程優先順序越低,越容易被殺回收;越小,表示進程優先順序越高,越不容易被殺回收
- 普通app進程的oom_adj>=0,系統進程的oom_adj才可能<0
那麼我們如何查看進程的oom_adj值呢,需要用到下面的兩個shell命令
ps | grep PackageName //擷取你指定的進程資訊
這裡是以我寫的demo代碼為例子,紅色圈中部分別為下面三個進程的ID
UI進程:com.clock.daemon
普通後台進程:com.clock.daemon:bg
灰色保活進程:com.clock.daemon:gray
當然,這些進程的id也可以通過AndroidStudio獲得
接著我們來再來擷取三個進程的oom_adj
cat /proc/進程ID/oom_adj
從可以看到UI進程和灰色保活Service進程的oom_adj=0,而普通後台進程oom_adj=15。到這裡估計你也能明白,為什麼普通的後台進程容易被回收,而前台進程則不容易被回收了吧。但明白這個還不夠,接著看
上面是我把app切換到後台,再進行一次oom_adj的檢驗,你會發現UI進程的值從0變成了6, 而灰色保活的Service進程則從0變成了1。這裡可以觀察到,app退到後台時,其所有的進程優先順序都會降低。但是UI進程是降低最為明顯的,因為它佔用的記憶體資源最多,系統記憶體不足的時候肯定優先殺這些佔用記憶體高的進程來騰出資源。所以,為了盡量避免後台UI進程被殺,需要儘可能的釋放一些不用的資源,尤其是圖片、音視頻之類的。
從Android官方文檔中,我們也能看到優先順序從高到低列出了這些不同類型的進程:Foreground process、Visible process、Service process、Background process、Empty process。而這些進程的oom_adj分別是多少,又是如何掛鈎起來的呢?推薦大家閱讀這篇文章: Android Low Memory Killer
總結
絮絮叨叨寫完了這麼多,最後來做個小小的總結。迴歸到開篇提到QQ進程不死的問題,我也曾認為存在這樣一種技術。可惜我把手機root後,殺掉QQ進程之後就再也起不來了。有些手機廠商把這些知名的app放入了自己的白名單中,保證了進程不死來提高使用者體驗(如、QQ、陌陌都在小米的白名單中)。如果從白名單中移除,他們終究還是和普通app一樣躲避不了被殺的命運,為了盡量避免被殺,還是老老實實去做好最佳化工作吧。
所以,進程保活的根本方案終究還是回到了效能最佳化上,進程永生不死終究是個徹頭徹尾的偽命題!補充更新 (2016-04-20)
有童鞋問,在華為的機子上發現和手Q的UI進程退到後台,oom_adj的值一點都沒有變,是不是有什麼黑科技在其中。為此,我稍稍驗證了一下,驗證方式就是把demo工程的包名改成手機QQ的,編譯運行在華為的機子上,發現我的進程怎麼殺也都是不死的,退到後台oom_adj的值同樣不發生變化,而恢複原來的包名就不行了。所以,你懂的,手Q就在華為機子的白名單中。
文章到此結束,相關簡單的實踐代碼請看
https://github.com/D-clock/AndroidDaemonService
附:
Android Low Memory Killer
關於 Android 進程保活,你所需要知道的一切
Android後台保活實踐總結:即時通訊應用無法根治的“頑疾”
Android進程回收機制LMK(Low Memory Killer)【轉】