大家知道要如何管理Android手機(jī)剩余內(nèi)存嗎?管理Android手機(jī)剩余內(nèi)存有什么方法?下面一起來看看!
目前創(chuàng)新互聯(lián)已為1000多家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站托管、服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、宜都網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
其實(shí)大家不用那么在意android手機(jī)剩余內(nèi)存的大小。
很多人都是把使用其他系統(tǒng)的習(xí)慣帶到了android手機(jī)上,不是所有的智能手機(jī)系統(tǒng)都一樣的。android大多數(shù)應(yīng)用沒有退出的設(shè)計(jì)其實(shí)是有道理的,這和系統(tǒng)對進(jìn)程的調(diào)度機(jī)制有關(guān)系。如果你知道java,就能更清楚這機(jī)制了。其實(shí)和java的垃圾回收機(jī)制類似,系統(tǒng)有一個(gè)規(guī)則來回收內(nèi)存。進(jìn)行內(nèi)存調(diào)度有個(gè)閥值,只有低于這個(gè)值系統(tǒng)才會按一個(gè)列表來關(guān)閉用戶不需要的東西。當(dāng)然這個(gè)值默認(rèn)設(shè)置得很小,所以你會看到內(nèi)存老在很少的數(shù)值徘徊。但事實(shí)上他并不影響速度。相反加快了下次啟動應(yīng)用的速度。這本來也是android的優(yōu)勢之一,如果人為去關(guān)閉進(jìn)程,沒有太大必要。特別是自動關(guān)進(jìn)程的軟件。
為什么內(nèi)存少的時(shí)候運(yùn)行大型程序會慢呢?
其實(shí)很簡單,在內(nèi)存剩余不多時(shí)打開大型程序,會觸發(fā)系統(tǒng)自身的調(diào)進(jìn)程調(diào)度策略,這是十分消耗系統(tǒng)資源的操作,特別是在一個(gè)程序頻繁向系統(tǒng)申請內(nèi)存的時(shí)候。這種情況下系統(tǒng)并不會關(guān)閉所有打開的進(jìn)程,而是選擇性關(guān)閉,頻繁的調(diào)度自然會拖慢系統(tǒng)。
進(jìn)程管理軟件到底還有存在的價(jià)值嗎?
其實(shí)還是有的,在運(yùn)行大型程序之前,你可以手動關(guān)閉一些進(jìn)程釋放內(nèi)存,可以顯著的提高運(yùn)行速度。但一些小程序,完全可交由系統(tǒng)自己管理。很多朋友還有個(gè)疑問,如果不關(guān)程序是不是會更耗電?這里也解釋一下,android的應(yīng)用在被切換到后臺時(shí),它其實(shí)已經(jīng)被暫停了,并不會消耗cpu資源,只保留了運(yùn)行狀態(tài)。所以為什么有的程序切出去重新進(jìn)入,還會到主界面。但是,一個(gè)程序如果想要在后臺處理些東西,如音樂播放,它就會開啟一個(gè)服務(wù),服務(wù)可在后臺持續(xù)運(yùn)行,所以在后臺耗電的也只有帶服務(wù)的應(yīng)用了。這個(gè)在進(jìn)程管理軟件里能看到,名字是service。所以沒有帶服務(wù)的應(yīng)用在后臺是完全不耗電的,沒有必要關(guān)閉。這種設(shè)計(jì)本來就是一個(gè)非常好的設(shè)計(jì),下次啟動程序時(shí),會更快,因?yàn)椴恍枰x取界面資源,何必要關(guān)掉他們抹殺這個(gè)android的優(yōu)點(diǎn)呢?
為什么android應(yīng)用看起來那么耗內(nèi)存?
大家知道,android上的應(yīng)用是java,當(dāng)然需要虛擬機(jī),而android上的應(yīng)用是帶有獨(dú)立虛擬機(jī)的,也就是每開一個(gè)應(yīng)用就會打開一個(gè)獨(dú)立的虛擬機(jī)。這樣設(shè)計(jì)的原因是可以避免虛擬機(jī)崩潰導(dǎo)致整個(gè)系統(tǒng)崩潰,但代價(jià)就是需要更多內(nèi)存。
至于為什么開了大程序或者開了好幾個(gè)程序之后切換會變慢,具體分析如下:
已經(jīng)開啟了一個(gè)大程序,占用70%內(nèi)存,如果再想運(yùn)行一個(gè)程序,此時(shí)還需要50%的內(nèi)存,則就需要一個(gè)從大程序占用的內(nèi)存中釋放或者壓縮的過程,所以表現(xiàn)出來的就是慢一會兒。
已經(jīng)開啟了幾個(gè)程序共占用內(nèi)存80%,運(yùn)行新程序時(shí)又需要20%的內(nèi)存,系統(tǒng)內(nèi)存因?yàn)闆]見過剩余0的時(shí)候,也就是應(yīng)該剩一部分空閑內(nèi)存,那么就需要從之前開啟的這幾個(gè)程序中選擇一個(gè)或者幾個(gè)來關(guān)閉,這一過程也需要耗費(fèi)系統(tǒng)資源,所以會慢一會兒。也就是說你手動去結(jié)束程序的時(shí)候,就是替系統(tǒng)在釋放內(nèi)存,就算你不去結(jié)束,在需要內(nèi)存的時(shí)候系統(tǒng)也會自動結(jié)束程序釋放內(nèi)存。
不在后臺運(yùn)行的程序(沒服務(wù)的),即使不結(jié)束也不會耗電。在后臺運(yùn)行的(有服務(wù)的`)程序,如一些播放器或?qū)崟r(shí)監(jiān)控的軟件,自然會耗電。這就說明結(jié)束進(jìn)程并不是沒用,我們只需要看哪個(gè)帶服務(wù)耗電哪個(gè)程序后臺一直在運(yùn)行,看服務(wù)就能看出來,這樣的軟件如果用不到的時(shí)候就結(jié)束了吧。
以QQ舉例,正常的退出,會在進(jìn)程管理里留下qq的運(yùn)行過的狀態(tài),但不耗電不占 cpu,如果你只是切換出去(按房子鍵而不是退出)那么自然會耗電,因?yàn)槌绦蜻€在運(yùn)行,QQ還在線呢。
這里就有個(gè)要注意的地方了,雖然房子鍵和那個(gè)返回鍵都可以將程序切換出去,但是兩者的效果差異是很大的,返回鍵可以視作程序已經(jīng)退出了,而按房子鍵,則是將程序切換到了后臺來運(yùn)行,軟件并沒有退出哦!
以上這些設(shè)計(jì)都是為了確保了android的穩(wěn)定性,正常情況下最多單個(gè)程序崩潰,但整個(gè)系統(tǒng)不會崩潰,也永遠(yuǎn)沒有內(nèi)存不足的提示出現(xiàn)。大家可能是被windows毒害得太深了,總想保留更多的內(nèi)存,但實(shí)際上這并不一定會提升速度,相反卻喪失了程序啟動快的這一系統(tǒng)特色,得不償失。大家不妨換種觀念習(xí)慣來使用android系統(tǒng)。
要獲取過去三小時(shí)內(nèi)應(yīng)用內(nèi)存占用情況統(tǒng)計(jì)信息可以使用如下命令:
會輸出應(yīng)用運(yùn)行時(shí)間百分比,以及PSS(分?jǐn)們?nèi)存大小),USS(獨(dú)占內(nèi)存大小),RSS(常駐內(nèi)存大小)(minPSS-avgPSS-maxPSS/minUSS-avgUSS-maxUSS/minRSS-avgRSS-maxRSS over 樣本數(shù))
參考:
vivo手機(jī)提示內(nèi)存不足處理方法:
手機(jī)運(yùn)行內(nèi)存不足:
1、調(diào)出后臺運(yùn)行軟件,一鍵加速清理后臺;
2、卸載手機(jī)中不常用的軟件(軟件的進(jìn)程、插件等會占用手機(jī)運(yùn)行內(nèi)存);
3、根據(jù)手機(jī)配置合理運(yùn)行軟件,若手機(jī)配置較低,盡量不要運(yùn)行對配置需求較高的大型游戲;
4、進(jìn)入手機(jī)設(shè)置--運(yùn)存與存儲空間--運(yùn)行內(nèi)存,開啟內(nèi)存融合,將RAM和ROM融合擴(kuò)展,沒有此選項(xiàng)則代表機(jī)型不支持。
手機(jī)存儲空間不足 :
1、進(jìn)入i管家--空間清理/空間管理--掃描并清理垃圾文件;
2、卸載手機(jī)中不常用的軟件,避免不必要的內(nèi)存占用;
3、進(jìn)入文件管理,對手機(jī)中的視頻、歌曲、壓縮包等進(jìn)行清理;
4、 部分支持SD卡的機(jī)型,可選擇安裝SD卡,將存儲在手機(jī)中的數(shù)據(jù)移動到SD卡存儲。
手機(jī)存儲空間足夠卻提示內(nèi)存不足 :
1、重啟一下手機(jī),查看是否恢復(fù)正常;
2、進(jìn)入設(shè)置--系統(tǒng)管理/更多設(shè)置--備份與重置--還原所有設(shè)置,該操作會導(dǎo)致登錄的第三方軟件賬號需要重新登錄,但不會清除手機(jī)存儲中的照片,視頻等文件,請確認(rèn)不影響某些第三方軟件的使用后再進(jìn)行還原所有設(shè)置操作。 避免操作出現(xiàn)異常導(dǎo)致數(shù)據(jù)丟失,建議先備份下手機(jī)的重要數(shù)據(jù);
3、進(jìn)入i管家--空間清理/空間管理--掃描并清理垃圾緩存;
4、必要時(shí),請先備份好手機(jī)中的重要數(shù)據(jù),進(jìn)入設(shè)置--系統(tǒng)管理/更多設(shè)置--備份與重置--清除所有數(shù)據(jù)試試。
手機(jī)運(yùn)行整個(gè)Android系統(tǒng)需要一定的內(nèi)存,部分系統(tǒng)程序和第三方程序也會開機(jī)自啟動,所以占用了較多的內(nèi)存,以致于開機(jī)后內(nèi)存占用率比較高。
若是使用vivo手機(jī),建議您時(shí)常一鍵加速來清理手機(jī)運(yùn)行內(nèi)存,并進(jìn)入i管家--(應(yīng)用管理/軟件管理)--權(quán)限管理--自啟動里面關(guān)閉不必要的自啟動軟件。
部分內(nèi)容出至林學(xué)森的Android內(nèi)核設(shè)計(jì)思想。
Android官網(wǎng)內(nèi)存管理
部分出至
Android本質(zhì)是Linux所以先從Linux說起。
Linux的內(nèi)存管理為系統(tǒng)中所有的task提供可靠的內(nèi)存分配、釋放和保護(hù)機(jī)制。
核心:
虛擬內(nèi)存
內(nèi)存分配與釋放
內(nèi)存保護(hù)
將外存儲器的部分空間作為內(nèi)存的擴(kuò)展,如從硬盤劃出4GB大小。
當(dāng)內(nèi)存資源不足時(shí),系統(tǒng)按照一定算法自動條形優(yōu)先級低的數(shù)據(jù)塊,并把他們存儲到硬盤中。
后續(xù)如果需要用到硬盤中的這些數(shù)據(jù)塊,系統(tǒng)將產(chǎn)生“缺頁”指令,然后把他們交換回內(nèi)存中。
這些都是由操作系統(tǒng)內(nèi)核自動完成的,對上層應(yīng)用”完全透明“。
每個(gè)進(jìn)程的邏輯地址和物理地址都不是直接對應(yīng)的,任何進(jìn)程都沒辦法訪問到它管轄范圍外的內(nèi)存空間——即刻意產(chǎn)生的內(nèi)存越界與非法訪問,操作系統(tǒng)也會馬上阻止并強(qiáng)行關(guān)閉程序,從而有力的保障應(yīng)用程序和操作系統(tǒng)的安全和穩(wěn)定。
一旦發(fā)現(xiàn)系統(tǒng)的可用內(nèi)存達(dá)到臨界值,機(jī)會按照優(yōu)先級順序,匆匆低到高逐步殺掉進(jìn)程,回收內(nèi)存。
存儲位置:/proc/PID/oom_score
優(yōu)先級策略:
進(jìn)程消耗的內(nèi)存
進(jìn)程占用的CPU時(shí)間
oom_adj(OOM權(quán)重)
Android平臺運(yùn)行的前提是可用內(nèi)存是浪費(fèi)的內(nèi)存。它試圖在任何時(shí)候使用所有可用的內(nèi)存。例如,系統(tǒng)會在APP關(guān)閉后將其保存在內(nèi)存中,以便用戶可以快速切換回它們。出于這個(gè)原因,Android設(shè)備通常運(yùn)行時(shí)只有很少的空閑內(nèi)存。在重要系統(tǒng)進(jìn)程和許多用戶應(yīng)用程序之間正確分配內(nèi)存內(nèi)對存管理是至關(guān)重要。
Android有兩種主要的機(jī)制來處理低內(nèi)存的情況:內(nèi)核交換守護(hù)進(jìn)程(kernel swap daemon)和低內(nèi)存殺手(low-memory killer)。
當(dāng)用戶在APP之間切換時(shí),Android會在最近使用的(LRU)緩存中保留不在前臺的APP,即用戶看不到的APP,或運(yùn)行類似音樂播放的前臺服務(wù)。如果用戶稍后返回APP,系統(tǒng)將重用該進(jìn)程,從而使APP切換更快。
如果你的APP有一個(gè)緩存進(jìn)程,并且它保留了當(dāng)前不需要的內(nèi)存,那么即使用戶不使用它,你的APP也會影響系統(tǒng)的整體性能。由于系統(tǒng)內(nèi)存不足,它會從最近使用最少的進(jìn)程開始?xì)⑺繪RU緩存中的進(jìn)程。該系統(tǒng)還負(fù)責(zé)處理占用最多內(nèi)存的進(jìn)程,并可以終止這些進(jìn)程以釋放RAM。
當(dāng)系統(tǒng)開始終止LRU緩存中的進(jìn)程時(shí),它主要是自底向上工作的。系統(tǒng)還考慮哪些進(jìn)程消耗更多的內(nèi)存,從而在終止時(shí)為系統(tǒng)提供更多的內(nèi)存增益。你在LRU列表中消耗的內(nèi)存越少,你就越有可能留在列表中并能夠快速恢復(fù)。
為了滿足RAM的所有需求,Android嘗試共享RAM來跨進(jìn)程通信。它可以做到以下方式:
Android設(shè)備包含三種不同類型的內(nèi)存:RAM、zRAM和storage。
注意:CPU和GPU都訪問同一個(gè)RAM。
內(nèi)存被拆分成頁。通常每頁有4KB的內(nèi)存。
頁面被認(rèn)為是空閑的或已使用的。
空閑頁是未使用的RAM。
已使用頁是系統(tǒng)正在積極使用的RAM,分為以下類別:
干凈的頁面(Clean pages)包含一個(gè)文件(或文件的一部分)的一份精確副本存在存儲器上。當(dāng)一個(gè)干凈的頁面不再包含一個(gè)精確的文件副本(例如,來自應(yīng)用程序操作的結(jié)果)時(shí),它就變成了臟頁??梢詣h除干凈的頁,因?yàn)樗鼈兪冀K可以使用存儲中的數(shù)據(jù)重新生成;不能刪除臟頁(Dirty pages),否則數(shù)據(jù)將丟失。
內(nèi)核跟蹤系統(tǒng)中的所有內(nèi)存頁。
當(dāng)確定一個(gè)應(yīng)用程序正在使用多少內(nèi)存時(shí),系統(tǒng)必須考慮shared pages。APP訪問相同的服務(wù)或庫將可能共享內(nèi)存頁。例如,Google Play Services 和一個(gè)游戲APP可能共享一個(gè)位置服務(wù)。這使得很難確定有多少內(nèi)存屬于這個(gè)服務(wù)相對于每個(gè)APP。
當(dāng)操作系統(tǒng)想要知道所有進(jìn)程使用了多少內(nèi)存時(shí),PSS非常有用,因?yàn)轫撁娌粫欢啻斡?jì)數(shù)。PSS需要很長時(shí)間來計(jì)算,因?yàn)橄到y(tǒng)需要確定哪些頁面是共享的,以及被有多少進(jìn)程。RSS不區(qū)分共享頁面和非共享頁面(使計(jì)算速度更快),更適合于跟蹤內(nèi)存分配的更改。
內(nèi)核交換守護(hù)進(jìn)程(kswapd)是Linux內(nèi)核的一部分,它將使用過的內(nèi)存轉(zhuǎn)換為空閑內(nèi)存。當(dāng)設(shè)備上的空閑內(nèi)存不足時(shí),守護(hù)進(jìn)程將變?yōu)榛顒訝顟B(tài)。Linux內(nèi)核保持低和高的可用內(nèi)存閾值。當(dāng)空閑內(nèi)存低于低閾值時(shí),kswapd開始回收內(nèi)存。當(dāng)空閑內(nèi)存達(dá)到高閾值,kswapd將停止回收內(nèi)存。
kswapd可以通過刪除干凈的頁面來回收干凈的頁面,因?yàn)樗鼈冇写鎯ζ髦С植⑶覜]有被修改。如果進(jìn)程試圖尋址已刪除的干凈頁,則系統(tǒng)會將該頁從存儲器復(fù)制到RAM。此操作稱為請求分頁。
kswapd將緩存的私有臟頁(private dirty pages)和匿名臟頁(anonymous dirty pages)移動到zRAM進(jìn)行壓縮。這樣做可以釋放RAM中的可用內(nèi)存(空閑頁)。如果進(jìn)程試圖觸摸zRAM中臟頁,則該頁將被解壓縮并移回RAM。如果與壓縮頁關(guān)聯(lián)的進(jìn)程被終止,則該頁將從zRAM中刪除。
如果可用內(nèi)存量低于某個(gè)閾值,系統(tǒng)將開始終止進(jìn)程。
lmkd實(shí)現(xiàn)源碼要在system/core/lmkd/lmkd.c。
lmkd會創(chuàng)建名為lmkd的socket,節(jié)點(diǎn)位于/dev/socket/lmkd,該socket用于跟上層framework交互。
小結(jié):
LMK_TARGET: AMS.updateConfiguration() 的過程中調(diào)用 updateOomLevels() 方法, 分別向/sys/module/lowmemorykiller/parameters目錄下的minfree和adj節(jié)點(diǎn)寫入相應(yīng)信息;
LMK_PROCPRIO: AMS.applyOomAdjLocked() 的過程中調(diào)用 setOomAdj() 向/proc/pid/oom_score_adj寫入oom_score_adj后直接返回;
LMK_PROCREMOVE: AMS.handleAppDiedLocked 或者 AMS.cleanUpApplicationRecordLocked() 的過程,調(diào)用remove(),目前不做任何事,直接返回;
為了進(jìn)一步幫助平衡系統(tǒng)內(nèi)存并避免終止APP進(jìn)程,可以Activity類中實(shí)現(xiàn)ComponentCallbacks2接口。提供的onTrimMemory()回調(diào)方法允許APP在前臺或后臺偵聽與內(nèi)存相關(guān)的事件,然后釋放對象以響應(yīng)應(yīng)用程序生命周期或表明系統(tǒng)需要回收內(nèi)存的系統(tǒng)事件。
onTrimMemory()回調(diào)是在Android 4.0(API級別14)中添加的。
對于早期版本,可以使用onLowMemory(),它大致相當(dāng)于TRIM_MEMORY_COMPLETE事件。
一個(gè)專門的驅(qū)動。(Linux Kernel 4.12 已移除交給kswapd處理)。
很多時(shí)候,kswapd無法為系統(tǒng)釋放足夠的內(nèi)存。在這種情況下,系統(tǒng)使用onTrimMemory()通知APP內(nèi)存不足,應(yīng)該減少其分配。如果這還不夠,內(nèi)核將開始終止進(jìn)程以釋放內(nèi)存,它使用低內(nèi)存殺手(LMK)來完成這個(gè)任務(wù)。
為了決定要終止哪個(gè)進(jìn)程,LMK使用一個(gè)名為oom_adj_score的“out of memory”分?jǐn)?shù)來確定運(yùn)行進(jìn)程的優(yōu)先級,高分的進(jìn)程首先被終止。
后臺應(yīng)用程序首先被終止,系統(tǒng)進(jìn)程最后被終止。
下表列出了從高到低的LMK評分類別。第一排得分最高的項(xiàng)目將首先被殺死:
Android Runtime(ART)和Dalvik虛擬機(jī)使用分頁(Paging)和內(nèi)存映射(mmapping)來管理內(nèi)存。應(yīng)用程序通過分配新對象或觸摸已映射頁面來修改內(nèi)存都將保留在RAM中,并且不能被調(diào)出。應(yīng)用程序釋放內(nèi)存的唯一方式是垃圾收集器。
內(nèi)存優(yōu)化就是對內(nèi)存問題的一個(gè)預(yù)防和解決,做內(nèi)存優(yōu)化能讓應(yīng)用掛得少、活得好和活得久。
掛的少:
“掛”指的是 Crash,內(nèi)存問題導(dǎo)致 Crash 的具體表現(xiàn)就是內(nèi)存溢出異常 OOM。
活得好:
活得好指的是使用流暢,Android 中造成界面卡頓的原因有很多種,其中一種就是由內(nèi)存問題引起的。內(nèi)存問題之所以會影響到界面流暢度,是因?yàn)槔厥眨℅C,Garbage Collection),在 GC 時(shí),所有線程都要停止,包括主線程,當(dāng) GC 和繪制界面的操作同時(shí)觸發(fā)時(shí),繪制的執(zhí)行就會被擱置,導(dǎo)致掉幀,也就是界面卡頓。
活得久:
活得久指的是我們的應(yīng)用在后臺運(yùn)行時(shí)不會被干掉。Android 會按照特定的機(jī)制清理進(jìn)程,清理進(jìn)程時(shí)優(yōu)先會考慮清理后臺進(jìn)程。清理進(jìn)程的機(jī)制就是LowMemoryKiller。在 Android 中不同的進(jìn)程有著不同的優(yōu)先級,當(dāng)兩個(gè)進(jìn)程的優(yōu)先級相同時(shí),低殺會優(yōu)先考慮干掉消耗內(nèi)存更多的進(jìn)程。也就是如果我們應(yīng)用占用的內(nèi)存比其他應(yīng)用少,并且處于后臺時(shí),我們的應(yīng)用能在后臺活下來,這也是內(nèi)存優(yōu)化為我們應(yīng)用帶來競爭力的一個(gè)直接體現(xiàn)。
內(nèi)存占用是否越少越好?
當(dāng)系統(tǒng) 內(nèi)存充足 的時(shí)候,我們可以多用 一些獲得更好的性能。當(dāng)系統(tǒng) 內(nèi)存不足 的時(shí)候,我們希望可以做到 ”用時(shí)分配,及時(shí)釋放“。內(nèi)存優(yōu)化并不能一刀切。
我們都知道,應(yīng)用程序的內(nèi)存分配和垃圾回收都是由Android虛擬機(jī)完成的,在Android 5.0以下,使用的是Dalvik虛擬機(jī),5.0及以上,則使用的是ART虛擬機(jī)。
Android虛擬機(jī)Dalvik和ART
1、內(nèi)存區(qū)域劃分
詳細(xì)請看以下兩篇文章(建議全看):
java內(nèi)存四大區(qū)_JVM內(nèi)存區(qū)域劃分
Android 內(nèi)存機(jī)制
2、內(nèi)存回收
垃圾收集的標(biāo)記算法(找到垃圾):
垃圾收集算法(回收垃圾):
引用類型:強(qiáng)引用、軟引用、弱引用、虛引用
對象的有效性=可達(dá)性+引用類型
JAVA垃圾回收機(jī)制-史上最容易理解看這一篇就夠了
Android:玩轉(zhuǎn)垃圾回收機(jī)制與分代回收策略
android中還存在低殺機(jī)制,這種情況屬于系統(tǒng)整機(jī)內(nèi)存不足,直接把應(yīng)用進(jìn)程殺掉的情況。
Android后臺殺死系列:LowMemoryKiller原理
1、內(nèi)存溢出
系統(tǒng)會給每個(gè)App分配內(nèi)存空間也就是heap size值,當(dāng)app占用的內(nèi)存加上申請的內(nèi)存超過這個(gè)系統(tǒng)分配的內(nèi)存限額,最終導(dǎo)致OOM(OutOfMemory)使程序崩潰。
通過命令 getprop |grep dalvik.vm.heapsize 可以獲取系統(tǒng)允許的最大
注意:在設(shè)置了heapgrowthlimit的狀況下,單個(gè)進(jìn)程可用最大內(nèi)存為heapgrowthlimit值。在android開發(fā)中,若是要使用大堆,須要在manifest中指定android:largeHeap為true,這樣dvm heap最大可達(dá)heapsize。
關(guān)于heapsize heapgrowthlimit
2、內(nèi)存泄漏
Android系統(tǒng)虛擬機(jī)的垃圾回收是通過虛擬機(jī)GC機(jī)制來實(shí)現(xiàn)的。GC會選擇一些還存活的對象作為內(nèi)存遍歷的根節(jié)點(diǎn)GC Roots,通過對GC Roots的可達(dá)性來判斷是否需要回收。內(nèi)存泄漏就是 在當(dāng)前應(yīng)用周期內(nèi)不再使用的對象被GC Roots引用,造成該對象無法被系統(tǒng)回收,以致該對象在堆中所占用的內(nèi)存單元無法被釋放而造成內(nèi)存空間浪費(fèi),使實(shí)際可使用內(nèi)存變小。簡言之,就是 對象被持有導(dǎo)致無法釋放或不能按照對象正常的生命周期進(jìn)行釋放。
Android常見內(nèi)存泄漏匯總
3、內(nèi)存抖動
指的是在短時(shí)間內(nèi)大量的新對象被實(shí)例化,運(yùn)行時(shí)可能無法承載這樣的內(nèi)存分配,在這種情況下就會導(dǎo)致垃圾回收事件被大量調(diào)用,影響到應(yīng)用程序的UI和整體性能,最終可能導(dǎo)致卡頓和OOM。
常見情況:在一些被頻繁調(diào)用的方法內(nèi)不斷地創(chuàng)建對象。例如在View 的onDraw方法內(nèi)new 一些新的對象。
注意內(nèi)存抖動也會導(dǎo)致 OOM,主要原因有如下兩點(diǎn):
1、Android Studio Profiler
作用
優(yōu)點(diǎn)
內(nèi)存抖動問題處理實(shí)戰(zhàn)
理解內(nèi)存抖動的概念的話,我們就能明白只要能找到抖動過程中所產(chǎn)生的對象及其調(diào)用棧,我們就能解決問題,剛好Android Studio 的Porfiler里面的Memory工具就能幫我們記錄下我們操作過程中或靜止界面所產(chǎn)生的新對象,并且能清晰看到這些對象的調(diào)用棧。
選擇Profile 中 的Memory ,選擇 Record Java/Kotlin allocations,再點(diǎn)擊Record開始記錄, Record Java/Kotlin allocations 選項(xiàng)會記錄下新增的對象。
操作完成之后,點(diǎn)擊如圖所示的紅腦按鈕,停止記錄。
停止記錄后,我們就可以排序(點(diǎn)擊 Allocations可以排序)看看哪些對象或基本類型在短時(shí)間被頻繁創(chuàng)建多個(gè),點(diǎn)擊這些新增的對象就可以看到它的完成的調(diào)用鏈了,進(jìn)而就找找到導(dǎo)致內(nèi)存抖動的地方在哪里了。
2、利用DDMS 和 MAT(Memory Analyzer tool)來分析內(nèi)存泄漏
我們利用工具進(jìn)行內(nèi)存泄漏分析主要是用對比法:
a.先打開正常界面,不做任何操作,先抓取一開始的堆文件。
b.一頓胡亂操作,回到原來操作前的界面。主動觸發(fā)一兩次GC,過10秒再抓取第二次堆文件。
c.通過工具對比,獲取胡亂操作后新增的對象,然后分析這些新增的對象。
DDMS作用:抓取堆文件,主動觸發(fā)GC。(其實(shí)也是可以用Android Studio 的Profile里面的Memory工具來抓取堆文件的,但是我這邊在利用Profile 主動觸發(fā)gc 的時(shí)候會導(dǎo)致程序奔潰,也不知道是不是手機(jī)的問題,所以沒用Android Studio的Profiler)
MAT作用:對堆文件進(jìn)行對比,找到多出的對象,找到對象的強(qiáng)引用調(diào)用鏈。
以下是詳細(xì)的過程:
步驟1.打開DDMS,選擇需要調(diào)試的應(yīng)用,打開初始界面,點(diǎn)擊下圖的圖標(biāo)(Dump Hprof File)先獲取一次堆文件。
步驟2.對應(yīng)用隨便操作后,回到一開始的界面,先多觸發(fā)幾次GC ,點(diǎn)擊下圖的圖標(biāo)(Cause Gc)來主動觸發(fā)GC,然后再次點(diǎn)擊 Dump Hprof File 圖標(biāo)來獲取堆文件。
步驟3.通過Android Studio Profile 或者 DDMS dump 的堆文件無法在MAT 打開,需要借助android sdk包下的一個(gè)工具h(yuǎn)prof-conv.exe來轉(zhuǎn)換。
格式為 hprof-conv 舊文件路徑名 要轉(zhuǎn)換的名稱;
例如:hprof-conv 2022-04-13_17-54-40_827.hprof change.hprof
步驟4.把兩份堆文件導(dǎo)入MAT,然后選擇其中第二次獲取的堆文件,點(diǎn)擊 如圖所示的 Histogram查看。
步驟5.點(diǎn)擊下圖圖標(biāo),Compare To Another Heap Dump ,選擇另一份堆文件。
6.會得出下圖所示的 Hitogram 展示,我們主要看Objects 這一列。 如下圖所示 “+ 2” 則代表前面兩份堆文件對比,這個(gè)對象多了兩個(gè),我們主要就是要分析這些多了出來,沒有被回收的對象。
7.加入我們從增加的對象中,看到了MainActivity ,則需要從一開始打開的Hitogram 展示里面找到這個(gè)對象的調(diào)用棧。如下圖所示,搜索MainActivity
8.看到下圖所示解雇,然后鼠標(biāo)右鍵點(diǎn)擊下圖紅色圈圈著的MainActivity ,選擇 Merger Shortest Paths to Gc Roots ,再選擇 exclude all phantom/weak/soft etc.references ,就可以看到這個(gè)MainActivity 對象的強(qiáng)引用鏈,至此我們就可以找到MainActivity對象是被什么引用導(dǎo)致無法回收了。
3、內(nèi)存泄露檢測神器之LeakCanary(線下集成)
自行學(xué)習(xí)了解,接入簡單,使用簡單,基本可以解決大部分內(nèi)存泄漏問題。
github地址 :
學(xué)習(xí)地址 :
針對內(nèi)存抖動的建議:
針對內(nèi)存泄漏問題的建議:
針對內(nèi)存溢出問題的建議(主要就是要減少內(nèi)存占用):
建議參考:
深入探索 Android 內(nèi)存優(yōu)化(煉獄級別)
對于 優(yōu)化的大方向,我們應(yīng)該優(yōu)先去做見效快的地方,主要有以下三部分:內(nèi)存泄漏、內(nèi)存抖動、Bitmap。完善監(jiān)控機(jī)制也是我們的重點(diǎn),能幫助我們對內(nèi)存問題快速分析和處理。
參考:
深入探索 Android 內(nèi)存優(yōu)化(煉獄級別)
網(wǎng)站題目:android應(yīng)用內(nèi)存,android應(yīng)用內(nèi)存最大是多少
路徑分享:http://www.rwnh.cn/article10/dsdjedo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、定制開發(fā)、手機(jī)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)公司、微信公眾號、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)