當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式軟件
[導(dǎo)讀] 相信一步步走過(guò)來(lái)的Android從業(yè)者,每個(gè)人都會(huì)遇到OOM的情況。如何避免和防范OOM的出現(xiàn),對(duì)于每一個(gè)程序員來(lái)說(shuō)確實(shí)是一門必不可少的能力。今天我們就談?wù)勗贏ndroid平臺(tái)下內(nèi)

 相信一步步走過(guò)來(lái)的Android從業(yè)者,每個(gè)人都會(huì)遇到OOM的情況。如何避免和防范OOM的出現(xiàn),對(duì)于每一個(gè)程序員來(lái)說(shuō)確實(shí)是一門必不可少的能力。今天我們就談?wù)勗贏ndroid平臺(tái)下內(nèi)存的管理之道,開始今天的主題之前,先再次回顧兩個(gè)概念。

內(nèi)存泄漏:對(duì)象在內(nèi)存heap堆中中分配的空間,當(dāng)不再使用或沒(méi)有引用指向的情況下,仍不能被GC正常回收的情況。多數(shù)出現(xiàn)在不合理的編碼情況下,比如在Activity中注冊(cè)了一個(gè)廣播接收器,但是在頁(yè)面關(guān)閉的時(shí)候進(jìn)行unRegister,就會(huì)出現(xiàn)內(nèi)存溢出的現(xiàn)象。通常情況下,大量的內(nèi)存泄漏會(huì)造成OOM。

OOM:即OutOfMemoery,顧名思義就是指內(nèi)存溢出了。內(nèi)存溢出是指APP向系統(tǒng)申請(qǐng)超過(guò)最大閥值的內(nèi)存請(qǐng)求,系統(tǒng)不會(huì)再分配多余的空間,就會(huì)造成OOM error。在我們Android平臺(tái)下,多數(shù)情況是出現(xiàn)在圖片不當(dāng)處理加載的時(shí)候。

內(nèi)存管理之道嘛,無(wú)非就是先理解并找出內(nèi)存泄漏的原因,再基于這些反式去合理的編碼,去防范進(jìn)而避免內(nèi)存開銷過(guò)大的情形。學(xué)習(xí)如何合理的管理內(nèi)存,最好先了解內(nèi)存分配的機(jī)制和原理。只有深層次的理解了內(nèi)部的原理,才能真正避免OOM的發(fā)生。但是本文就不介紹Jvm/Davilk內(nèi)存分配的機(jī)制了,如有興趣,請(qǐng)查看歷史消息,以前做過(guò)題為《JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)域分析》的分享。

Android APP的所能申請(qǐng)的最大內(nèi)存大小是多少,有人說(shuō)是16MB,有人又說(shuō)是24MB。這種事情,還是親自用自己的手機(jī)測(cè)試下比較靠譜。測(cè)試方式也比較簡(jiǎn)單,Java中有個(gè)Runtime類,主要用作APP與運(yùn)行環(huán)境交互,APP并不會(huì)為我們創(chuàng)建Runtime的實(shí)例,但是Java為我們提供了單例獲取的方式Runtime.getRuntime()。通過(guò)maxMemory()方法獲取系統(tǒng)可為APP分配的最大內(nèi)存,totalMemory()獲取APP當(dāng)前所分配的內(nèi)存heap空間大小。我手上有兩部手機(jī),一部Oppo find7,運(yùn)行Color OS,實(shí)測(cè)最大內(nèi)存分配為192MB;一部天語(yǔ)v9,運(yùn)行小米系統(tǒng),實(shí)測(cè)最大內(nèi)存分配為100MB。這下看出點(diǎn)眉目了吧,由于Android是開源系統(tǒng),不同的手機(jī)廠商其實(shí)是擁有修改這部分權(quán)限能力的,所以就造成了不同品牌和不同系統(tǒng)的手機(jī),對(duì)于APP的內(nèi)存支持也是不一樣的,和IOS的恒久100MB是不同的。一般來(lái)說(shuō),手機(jī)內(nèi)存的配置越高,廠商也會(huì)調(diào)大手機(jī)支持的內(nèi)存最大閥值,尤其是現(xiàn)在旗艦機(jī)滿天發(fā)布的情況下。但是開發(fā)者為了考慮開發(fā)出的APP的內(nèi)存兼容性,無(wú)法保證APP運(yùn)行在何種手機(jī)上,只能從編碼角度來(lái)優(yōu)化內(nèi)存了。

下面我們逐條來(lái)分析Android內(nèi)存優(yōu)化的關(guān)鍵點(diǎn)。

1、萬(wàn)惡的static

static是個(gè)好東西,聲明賦值調(diào)用就是那么的簡(jiǎn)單方便,但是伴隨而來(lái)的還有性能問(wèn)題。由于static聲明變量的生命周期其實(shí)是和APP的生命周期一樣的,有點(diǎn)類似與Application。如果大量的使用的話,就會(huì)占據(jù)內(nèi)存空間不釋放,積少成多也會(huì)造成內(nèi)存的不斷開銷,直至掛掉。static的合理使用一般用來(lái)修飾基本數(shù)據(jù)類型或者輕量級(jí)對(duì)象,盡量避免修復(fù)集合或者大對(duì)象,常用作修飾全局配置項(xiàng)、工具類方法、內(nèi)部類。

2、無(wú)關(guān)引用

很多情況下,我們需求用到傳遞引用,但是我們無(wú)法確保引用傳遞出去后能否及時(shí)的回收。比如比較有代表性的Context泄漏,很多情況下當(dāng)Activity 結(jié)束掉后,由于仍被其他的對(duì)象指向?qū)е乱恢边t遲不能回收,這就造成了內(nèi)存泄漏。這時(shí)可以考慮第三條建議。

3、善用SoftReference/WeakReference/LruCache

Java、Android中有沒(méi)有這樣一種機(jī)制呢,當(dāng)內(nèi)存吃緊或者GC掃過(guò)的情況下,就能及時(shí)把一些內(nèi)存占用給釋放掉,從而分配給需要分配的地方。答案是肯定的,java為我們提供了兩個(gè)解決方案。如果對(duì)內(nèi)存的開銷比較關(guān)注的APP,可以考慮使用WeakReference,當(dāng)GC回收掃過(guò)這塊內(nèi)存區(qū)域時(shí)就會(huì)回收;如果不是那么關(guān)注的話,可以使用SoftReference,它會(huì)在內(nèi)存申請(qǐng)不足的情況下自動(dòng)釋放,同樣也能解決OOM問(wèn)題。同時(shí)Android自3.0以后也推出了LruCache類,使用LRU算法就釋放內(nèi)存,一樣的能解決OOM,如果兼容3.0一下的版本,請(qǐng)導(dǎo)入v4包。關(guān)于第二條的無(wú)關(guān)引用的問(wèn)題,我們傳參可以考慮使用WeakReference包裝一下。

4、謹(jǐn)慎handler

在處理異步操作的時(shí)候,handler + thread是個(gè)不錯(cuò)的選擇。但是相信在使用handler的時(shí)候,大家都會(huì)遇到警告的情形,這個(gè)就是lint為開發(fā)者的提醒。handler運(yùn)行于UI線程,不斷處理來(lái)自MessageQueue的消息,如果handler還有消息需要處理但是Activity頁(yè)面已經(jīng)結(jié)束的情況下,Activity的引用其實(shí)并不會(huì)被回收,這就造成了內(nèi)存泄漏。解決方案,一是在Activity的onDestroy方法中調(diào)用

handler.removeCallbacksAndMessages(null);取消所有的消息的處理,包括待處理的消息;二是聲明handler的內(nèi)部類為static。

5、Bitmap終極殺手

Bitmap的不當(dāng)處理極可能造成OOM,絕大多數(shù)情況都是因這個(gè)原因出現(xiàn)的。Bitamp位圖是Android中當(dāng)之無(wú)愧的胖小子,所以在操作的時(shí)候當(dāng)然是十分的小心了。由于Dalivk并不會(huì)主動(dòng)的去回收,需要開發(fā)者在Bitmap不被使用的時(shí)候recycle掉。使用的過(guò)程中,及時(shí)釋放是非常重要的。同時(shí)如果需求允許,也可以去BItmap進(jìn)行一定的縮放,通過(guò)BitmapFactory.Options的inSampleSize屬性進(jìn)行控制。如果僅僅只想獲得Bitmap的屬性,其實(shí)并不需要根據(jù)BItmap的像素去分配內(nèi)存,只需在解析讀取Bmp的時(shí)候使用BitmapFactory.Options的inJustDecodeBounds屬性。最后建議大家在加載網(wǎng)絡(luò)圖片的時(shí)候,使用軟引用或者弱引用并進(jìn)行本地緩存,推薦使用android-universal-imageloader或者xUtils,牛人出品,必屬精品。前幾天在講《自定義控件(三) 繼承控件》的時(shí)候,也整理一個(gè),大家可以去Github下載看看。

6、Cursor及時(shí)關(guān)閉

在查詢SQLite數(shù)據(jù)庫(kù)時(shí),會(huì)返回一個(gè)Cursor,當(dāng)查詢完畢后,及時(shí)關(guān)閉,這樣就可以把查詢的結(jié)果集及時(shí)給回收掉。

7、頁(yè)面背景和圖片加載

在布局和代碼中設(shè)置背景和圖片的時(shí)候,如果是純色,盡量使用color;如果是規(guī)則圖形,盡量使用shape畫圖;如果稍微復(fù)雜點(diǎn),可以使用9patch圖;如果不能使用9patch的情況下,針對(duì)幾種主流分辨率的機(jī)型進(jìn)行切圖。

8、ListView和GridView的item緩存

對(duì)于移動(dòng)設(shè)備,尤其硬件參差不齊的android生態(tài),頁(yè)面的繪制其實(shí)是很耗時(shí)的,findViewById也是蠻慢的。所以不重用View,在有列表的時(shí)候就尤為顯著了,經(jīng)常會(huì)出現(xiàn)滑動(dòng)很卡的現(xiàn)象。具體參照歷史文章《說(shuō)說(shuō)ViewHolder的另一種寫法》[!--empirenews.page--]

9、BroadCastReceiver、Service

綁定廣播和服務(wù),一定要記得在不需要的時(shí)候給解綁。

10、I/O流

I/O流操作完畢,讀寫結(jié)束,記得關(guān)閉。

11、線程

線程不再需要繼續(xù)執(zhí)行的時(shí)候要記得及時(shí)關(guān)閉,開啟線程數(shù)量不易過(guò)多,一般和自己機(jī)器內(nèi)核數(shù)一樣最好,推薦開啟線程的時(shí)候,使用線程池。

12、String/StringBuffer

當(dāng)有較多的字符創(chuàng)需要拼接的時(shí)候,推薦使用StringBuffer。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉