Android 系統不釋放內存嗎?
android系統下關閉程序後,系統內存並不釋放。即使關掉後台進程,內存也增加不多。據說即使前台關掉進程,其實該進程在後台還在運行(休眠)。why?有人說是因為智能手機無需將程序徹底關掉,可以減少再啟動的時間。是這樣嗎?
我來逐條回答你的問題把
1. android系統下關閉程序後,系統內存並不釋放。
這個是不準確的,只能說對了一半. 你所描述的"android系統下關閉程序",指的是怎麼個關閉法呢?目前階段有好幾種關閉程序的方法:
點擊Back鍵退出. 這種退出的方法, 進程是否被殺掉,取決於這個應用程序的實現. 舉個栗子,如果你創建一個空的應用, 這時候查看系統內存信息(包名為com.exmaple.gaojianwu.myapplication,pid為5708,內存為13910kb):
可以看到,這個應用程序的pid為5708 , 其優先順序為Foreground,即前台程序.
這時候我們點擊Back鍵退出,然後再查看系統的內存信息(adb shell dumpsys meminfo)
我們看到,這個程序在Back鍵之後,其進程5708依舊是存在的.只是其進程優先順序變成了Cache.其佔用內存變成了12337kb,和之前的13910kb相比是變小了一些. 但是大部分內存是沒有被釋放掉的.
在任務管理器中殺掉應用:
在任務管理器中殺掉應用,這個結果是不一致的,其取決於這個OS的任務管理器的實現,大部分國內的廠家都會對任務管理器進行定製,以達到更有效的殺掉應用的效果.一般來說廠家定製的任務管理器都會比較暴力,除了少數白名單,其他的應用一概直接將進程殺掉.
我們以上面的那個測試程序為例,打開這個程序之後, 其進程優先順序為Foreground,這時候我們直接調用任務管理器殺掉改程序(以魅族MX4 Pro為栗子):
可以看到用任務管理器殺掉之後, 整個應用程序的進程都被殺掉了.
通過命令行或者開發者工具殺掉應用.
我們可以通過adb shell am force-stop 包名來殺掉這個程序,其結果也是進程直接被殺掉. IDE(比如Android Studio)選擇一個進程後,點擊:
也是可以幹掉這個進程的.
2. 即使關掉後台進程,內存也增加不多。
這個不對,一個進程被殺死後,其內存會被釋放掉的.
我們以知乎App Android客戶端為栗子:
打開這個程序之前,系統剩餘內存,以(MX4 Pro為栗子):
打開這個程序之後,系統剩餘內存:
知乎佔用的內存:
使用任務管理器殺掉知乎,系統剩餘內存:
可以看到,殺掉進程之後,內存是會增加的.
3. 據說即使前台關掉進程,其實該進程在後台還在運行(休眠)。why?
這個和第一條一樣,取決於你關掉進程的方法.
另外像豌豆莢這樣的應用,他會起好幾個進程:
當我們用任務管理器殺掉他後,
這個進程不會被殺掉. 因為人家就是需要在後台跑一個Services來維持usb的鏈接.休眠?NO NO NO, 人家還是要幹活的...
想想也是哈,如果我把這個進程也幹掉了,那手機不就連不上電腦了么???
以此類推:
要是我把QQ的
幹掉的話,不就收不到推送信息了? 不行不行,得留著.
要是......................?不行不行,得留著.
要是......................?不行不行,得留著.
要是......................?不行不行,得留著.
要是......................?不行不行,得留著.
要是......................?不行不行,得留著.
警告:系統內存不足!!!!!!!!!!!!
系統:殺殺殺!
用戶:啥破手機,老是殺我後台!!!
手機:怪我咯?
APP:怪我咯?
程序員: 怪我咯? 產品狗說要加這麼多功能的, 還要一直後台接受消息的..
產品狗: 怪我咯? 自己技術不行...
4. 有人說是因為智能手機無需將程序徹底關掉,可以減少再啟動的時間。是這樣嗎?
這個說法前半句是不對的,後半句是對的.
先說前半句 : Android設計的時候,確實是想讓大家不去關心內存問題,Android會有一套自己的內存管理機制,在內存不足的時候通過優先順序幹掉一些應用,這個 @monkey code 已經說了. 每個應用在接收到內存不足的信號(之前是onLowMemory,現在一般用onTrimMemory,onLowMemory的級別相當於onTrimMemory中的最嚴重的哪個等級). 會根據內存不足的程度,來釋放掉一部分內存.以保持自己的進程不被殺死,這樣下次啟動的時候就不用去fork zygote. 但是.................凡是總有個但是, 理想是豐滿的,現實是骨幹的. 嚴格按照Google想的那一套去做的應用不多,國內開發者對內存的敏感程度很低,導致很多應用程序跑起來分分鐘就100-200MB了,墨跡天氣這樣的應用,400m妥妥的(不好意思又黑了墨跡天氣) . 所以手機低內存的情況非常常見,這時候大部分應用並沒有重寫onTrimMemory方法, 所以低內存的情況會很頻繁. 這時候你再起一個應用,申請內存的時候發現內存不夠,就開始殺應用了. 所以經常會出現你在看電子書,突然這時候微信來了個消息,你切過去回了個消息,打開相機拍了個照,然後發給朋友, 又發了條微博,再回來
看書的時候發現電子書已經掛了,正在重新載入程序....WLGQ...
這時候你就發現殺掉進程的重要性了, 把不重要的進程直接幹掉,保證重要的進程不會被系統殺掉.
所以說不重要的程序是需要在使用結束後直接幹掉的.一勞永逸,麻麻再也不用擔心這貨偷跑流量/後台安裝程序/占內存/佔CPU 了....
再說後半句: 可以減少啟動的時間. 這個是對的, 如果一個應用程序的進程沒有被殺死,那麼下一次啟動這個應用程序的時候,就不需要去創建這個進程了(fork zygote,這個耗時還是蠻多的), 而是直接在這個進程中創建對應的組件即可(Android四大組件).
update 2015-6-3
補充:
1. 關於墨跡天氣
下面是我抓的墨跡天氣的內存使用:
三個進程,一個在Native,一個是前台進程,還有一個推送的Service。
2. 內存工具
另外有人問我是怎麼抓的,其實就是上面提到的那個命令:
adb shell dumpsys meminfo
彈出的框選第三個:
然後就會有一個報告自動打開。
簡單點說,這樣做的好處就是再次打開這個應用的時候速度會變快,因為節省了fork,重新解析載入布局等操作,直接resume就可以了,這個也就是冷啟動和熱啟動的區別。
這樣做的是基於OOM_ADJ的,當系統內存的壓力值達到某個地步的時候,就會開始殺對應優先順序的進程。
一個很好的例子就是當你進入大遊戲後回到主菜單,主菜單會有一個重新載入的過程,但是狀態欄就沒有,這個過程簡單點說可以是這樣的:
進入大遊戲,逐漸申請內存,前台大遊戲的OOM_ADJ值是0,後台的launcher是6,當逐漸內存壓力變大的時候,lmk就開始殺進程,於是從最低優先順序的進程(CACHED_APP_MAX_ADJ = 15)殺起,一路殺到launcher,如果發現夠了,就不再殺。
而從大遊戲退出到launcher後,重新創建launcher,於是有了重新載入的過程。
而systemui由於是persist進程優先順序為-12,因此不會殺到。
這個問題之前和同事討論過,基本是 @cottageinminsk 說得那樣,也不詳細表述了。另外,在討論這個問題時候,還題到ios內存管理,發現好像ios程序退出直接kill 程序,釋放內存,在使用ios手機時候會發現,有消息推送,比如微信接收消息時候。明明手機的狀態欄顯示出來了消息信息,下拉狀態欄點擊進入微信,微信還的重新載入數據。
Android系統釋放內存,但是是在需要的內存超出現有空閑內存的時候
OSX、Windows、iOS也是如此
我的愚見是:之前使用過的手機基本上都遵循這個規律
1.一鍵清理後台之後,你可以到「系統設置-所有應用程序」的地方看看,正在運行的程序之中會有一些沒有成功清理,這就是傳說中的不清理後台的程序列表,大概就是系統自願或者不自願地把它們放進了白名單。例如微信,微博,音樂播放器。通常,我會選擇點擊這些程序手動停止,遇到部分比較頑強的抵抗,我也只有從了。
2.同樣在正在運行的界面,點擊顯示「緩存後台程序」,這些程序和前面的不同,一般是不會佔用系統內存的,也就是非活躍的內存區域,簡而言之可以忽略,而且你也無法手動停止他們。
3.根據以上兩點現象,我們討論一下android的後台機制,和WP,ios那種假後台不同,安卓系統和windows比較類似,採用了多任務的機制,所以原則上內存越大,能夠並行的多任務越多。如果有一鍵清理,強迫症的用戶,例如我,就會經常點擊一下,這是手動釋放內存的方法。安卓自動釋放內存的規律是,等到內存池溢出,安卓系統才會強制根據演算法進行篩選,將最不常用的進程,或者最早的進程砍掉,騰出空間。
4.這就是你總感覺系統不流暢,尤其是切換多任務的時候,出現了部分應用假死也是常有的事,這好比windows,我們也要經常到資源管理器殺進程
5.一鍵清理後台也有弊病,當我們過於頻繁清理後台之後,我們會發現部分應用打開的時間,切換應用的時間同樣需要等待,這時候不是內存空間不足導致,而是重新載入到內存所導致。
6.所以即使是升級到android4.4之後,我也不建議用戶購買1GB內存以下的機型,因為隨著我們並行的任務逐漸增多,谷歌再優化也是無補於是,倒不如根據我們的使用習慣,適當地選擇大內存的手機更划算,2GB機型已經開始普及到千元以下的價位,3GB基本上成為旗艦機標配,今年,華碩,樂視的機型也上了4GB的配置,所以只要不是ios和WP陣營,大內存還是很有必要的。
在內存足夠的情況下內核本來就不應該真的「釋放」內存
一個進程所佔用的內存包括,程序的二進位代碼,數據區,還有內核維護的進程狀態字,頁表等數據結構。
在進程退出的時候,內核會在釋放完所有資源後,把已經沒有用處的數據結構所佔用的內存「標記為空閑」,把進程運行中分配的數據區「標記為空閑」,但是對於程序曾經打開的文件,包括本身的程序文件,操作系統不會「標記為空閑」,而是「標記為緩存」。
其中比較重要的一點是,不管是空閑還是緩存,都只是存儲管理子系統的一個flag而已,在空閑空間不足時,緩存自然會分配作新的目的,而且並不會增加這個分配過程的耗時。
也就是說,不論是「空閑」還是「緩存」,都是「可用內存」,而使用緩存還能減少IO,所以說,是更好的做法。安卓系統相對比較開放,正常的程序開發者,如果考慮用戶體驗,以及考慮到了系統的優化,會考慮到你提出的問題,但是一些程序員並不了解系統該如何優化,只是實現了一些功能,這樣就容易導致,軟體看起來退出了,其實還佔著內存。
如果你是正常的用戶,一個普通的安卓用戶,你可以下載一些清理手機的軟體(BAT等各大公司都有相關產品,看你自己喜歡哪個就用哪個給手機加速就行),直接清理掉就行了,就不用擔心程序退出還佔內存的問題。
如果你是一個程序員,想了解怎麼退出後不佔內存,那麼可以看下樓上高爺的分析,然後在寫程序的時候多家注意程序優化。不不不,它只是釋放的不及時而已
安卓有自己的內存管理機制,但是生效的前提是建立在所有軟體都嚴格按照谷歌開發規範開發的基礎上,用此類的應用程序完全不用考慮是不是要退出、是不是要清理內存等問題,而且把內存交給系統管理還會提高系統流暢度,打開軟體會比冷啟動快,提高內存利用率。然而現實很殘酷,還是有很多APP不會按照規範開發,有的直接從ios移植,程序佔用內存、駐留各種服務在後台,導致系統卡頓、內存佔用多、增加一些耗電等問題。
說了這麼多,簡單來說就定時清理一下吧,不需要太勤,一般軟體掛後台增加的耗電是極少的。
我記得入門開始有講
關鍵是好多用戶不這麼看,用戶喜歡拿這個廠家、那個廠家的機器對比,看人家剩餘內存xx G,你這幾百M。Android5以後內存計算方式默認都比4.x多,況且還有ART。
如果大部分APP都能考慮到手機廠商和用戶的心聲,就不要為了自己的活躍度,留存率,用各種漏洞、黑科技提高自己app的oom_adj值,避免自己被殺;其次,在後台再留幾個進程,相互拉,監聽各種系統廣播,使用不待機的wakelock、alarm定時喚醒。。。 一個個都這麼玩,機器不卡、不費電都是傳說,然而現實就是這樣。
現在標配都是4G+32G+3000+mAH,很快就6G+128G+4000mAH了...
for i in JIT緩存 Java+GC; do
echo 」你 Google 一下 $i 會死?"
done
還是Xbox 360, PS3,PS4系統最省事。 退出遊戲絕對完全退出,絕對單任務運行。 小小一台手機,只有PS4的十分之一大小,居然敢搞多任務,管理內存,不自量力!
推薦閱讀:
※Android 系統究竟用到了微軟的哪些專利?
※有哪些優秀應用只有 Android 版而無 iOS 版?
※老師給了個創新項目:基於北斗衛星的導航系統 。具體是做一個 Android 應用程序 , 通過接收來自北斗衛星導航系統的定位數據,然後調用Google地圖 , 顯示用戶所在位置和周邊地圖 。我想問的是:是否可行?
※Android上你覺得最好的新浪微博客戶端是啥?官方、weico、YiBo?博微博?其他?
※JAVA 學到什麼水平就可以轉戰 Android 了?