成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Android內(nèi)存泄露的解決之道

ConardLi / 847人閱讀

摘要:導(dǎo)致了當(dāng)旋轉(zhuǎn)屏幕時(shí),無法被回收,而造成內(nèi)存泄露。但是,她卻會(huì)造成嚴(yán)重的內(nèi)存泄露。參考內(nèi)存泄露問題的整理內(nèi)存泄露使用中可能引發(fā)的內(nèi)存泄漏介紹了內(nèi)存泄露有關(guān)的解決辦法,下一篇總結(jié)遇到時(shí)的解決之道。

面試的時(shí)候經(jīng)常會(huì)被問道內(nèi)存泄露優(yōu)化,和碰到OOM該怎么出來,今天就做個(gè)總結(jié)。

為什么會(huì)內(nèi)存泄露?

根本原因就是一個(gè)永遠(yuǎn)不會(huì)被使用的對(duì)象,因?yàn)橐恍┮脹]有斷開,沒有滿足GC條件,導(dǎo)致不會(huì)被回收,這就造成了內(nèi)存泄露。比如在Activity中注冊(cè)了一個(gè)廣播接收器,但是在頁面關(guān)閉的時(shí)候沒有進(jìn)行unRegister,就會(huì)出現(xiàn)內(nèi)存溢出的現(xiàn)象。如果我們的java運(yùn)行很久,而這種內(nèi)存泄露不斷的發(fā)生,最后就沒內(nèi)存可用了,最終就是我們??吹降腛OM錯(cuò)誤。

如何來解決內(nèi)存泄露 持有Context引用造成的泄露

在Android應(yīng)用程序中通??梢允褂脙煞NContext對(duì)象:Activity和Application。當(dāng)類或方法需要Context對(duì)象的時(shí)候常見的做法是使用第一個(gè)作為Context參數(shù)。這樣就意味著View對(duì)象對(duì)整個(gè)activity保持引用,因此也就保持對(duì)activty的所有的引用。

假設(shè)一個(gè)場(chǎng)景,當(dāng)應(yīng)用程序有個(gè)比較大的bitmap類型的圖片,每次旋轉(zhuǎn)是都重新加載圖片所用的時(shí)間較多。為了提高屏幕旋轉(zhuǎn)是Activity的創(chuàng)建速度,最簡(jiǎn)單的方法時(shí)將這個(gè)Bitmap對(duì)象使用static修飾。
當(dāng)一個(gè)Drawable綁定在View上,實(shí)際上這個(gè)View對(duì)象就會(huì)成為這份Drawable的一個(gè)callback成員變量。而靜態(tài)變量的生命周期要長(zhǎng)于Activity。導(dǎo)致了當(dāng)旋轉(zhuǎn)屏幕時(shí),Activity無法被回收,而造成內(nèi)存泄露。

解決的方法
使用Application對(duì)象,這個(gè)對(duì)象會(huì)隨著應(yīng)用程序的存在而存在,而不依賴于activity的生命周期。如果打算對(duì)context對(duì)象進(jìn)行長(zhǎng)期的引用,一定要記住用application對(duì)象
總結(jié):避免context泄露:

盡量使用Application的context類型。

對(duì)Context的引用不要超過它本身的生命周期,慎重的對(duì)Context使用“static”關(guān)鍵字。Context里如果有線程,一定要在onDestroy()里及時(shí)停掉。

Handler造成的內(nèi)存泄露
    public class SampleActivity extends Activity {
      private final Handler mLeakyHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
          // ... 
        }
      }
    }

在使用handler時(shí),這時(shí)一段很常見的代碼。但是,她卻會(huì)造成嚴(yán)重的內(nèi)存泄露。
假設(shè)當(dāng)Handler中有延遲的的任務(wù)或是等待執(zhí)行的任務(wù)隊(duì)列過長(zhǎng),由于消息持有對(duì)handler的引用,而handler又持有對(duì)其外部類的潛在引用,這條引用關(guān)系會(huì)一直保持到消息得到處理,而導(dǎo)致了activity無法被垃圾回收器回收,而導(dǎo)致了內(nèi)存泄露。

在java里,非靜態(tài)內(nèi)部類 和 匿名類 都會(huì)潛在的引用它們所屬的外部類。但是,靜態(tài)內(nèi)部類卻不會(huì)

解決方法

可以把handler類放在多帶帶的類文件中,或者使用靜態(tài)內(nèi)部類便可以避免泄露。

如果想在handler內(nèi)部去調(diào)用所在的Activity,那么可以在handler內(nèi)部使用弱引用的方式去指向所在Activity.使用Static + WeakReference的方式來達(dá)到斷開Handler與Activity之間存在引用關(guān)系的目的。

Bitmap沒有及時(shí)回收造成的內(nèi)存泄露

Bitmap對(duì)象不在使用時(shí)調(diào)用recycle()釋放內(nèi)存。2.3以后的bitmap應(yīng)該是不需要手動(dòng)recycle了,內(nèi)存已經(jīng)在java層了

資源對(duì)象沒關(guān)造成的內(nèi)存泄露

資源性對(duì)象比如(Cursor,F(xiàn)ile文件等)往往都用了一些緩沖,我們?cè)诓皇褂玫臅r(shí)候,應(yīng)該及時(shí)關(guān)閉它們,以便它們的緩沖及時(shí)回收內(nèi)存。它們的緩沖不僅存在于 java虛擬機(jī)內(nèi),還存在于java虛擬機(jī)外。如果我們僅僅是把它的引用設(shè)置為null,而不關(guān)閉它們,往往會(huì)造成內(nèi)存泄漏。因?yàn)橛行┵Y源性對(duì)象,比如 SQLiteCursor(在析構(gòu)函數(shù)finalize(),如果我們沒有關(guān)閉它,它自己會(huì)調(diào)close()關(guān)閉),如果我們沒有關(guān)閉它,系統(tǒng)在回收它時(shí)也會(huì)關(guān)閉它,但是這樣的效率太低了。因此對(duì)于資源性對(duì)象在不使用的時(shí)候,應(yīng)該調(diào)用它的close()函數(shù),將其關(guān)閉掉,然后才置為null.在我們的程序退出時(shí)一定要確保我們的資源性對(duì)象已經(jīng)關(guān)閉。

構(gòu)造Adapter時(shí),沒有使用緩存的convertView

初始時(shí)ListView會(huì)從BaseAdapter中根據(jù)當(dāng)前的屏幕布局實(shí)例化一定數(shù)量的view對(duì)象,同時(shí)ListView會(huì)將這些view對(duì)象 緩存起來。
當(dāng)向上滾動(dòng)ListView時(shí),原先位于最上面的list item的view對(duì)象會(huì)被回收,然后被用來構(gòu)造新出現(xiàn)的最下面的list item。
這個(gè)構(gòu)造過程就是由getView()方法完成的,getView()的第二個(gè)形參View convertView就是被緩存起來的list item的view對(duì)象(初始化時(shí)緩存中沒有view對(duì)象則convertView是null)。

注意監(jiān)聽器的注銷

在Android程序里面存在很多需要register與unregister的監(jiān)聽器,我們需要確保及時(shí)unregister監(jiān)聽器。

緩存容器中的內(nèi)存泄露

我們通常把一些對(duì)象的引用加入到了集合容器(比如ArrayList)中,當(dāng)我們不需要該對(duì)象時(shí),
并沒有把它的引用從集合中清理掉,這樣這個(gè)集合就會(huì)越來越大。如果這個(gè)集合是static的話,那情況就更嚴(yán)重了。
所以要在退出程序之前,將集合里的東西clear,然后置為null,再退出程序。

webView造成的泄露

當(dāng)我們不要使用WebView對(duì)象時(shí),應(yīng)該調(diào)用它的destory()函數(shù)來銷毀它,并釋放其占用的內(nèi)存,否則其占用的內(nèi)存長(zhǎng)期也不能被回收,從而造成內(nèi)存泄露。
解決方法
為webView開啟另外一個(gè)進(jìn)程,通過AIDL與主線程進(jìn)行通信,WebView所在的進(jìn)程可以根據(jù)業(yè)務(wù)的需要選擇合適的時(shí)機(jī)進(jìn)行銷毀,從而達(dá)到內(nèi)存的完整釋放。

參考:
Andriod 內(nèi)存泄露問題的整理
Android_內(nèi)存泄露
Handler使用中可能引發(fā)的內(nèi)存泄漏

介紹了內(nèi)存泄露有關(guān)的解決辦法,下一篇總結(jié)遇到OOM時(shí)的解決之道。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/65606.html

相關(guān)文章

  • LeakCanary傻瓜式內(nèi)存泄露檢測(cè)工具

    摘要:另一種方式就是是一個(gè)簡(jiǎn)單的,方便的內(nèi)存檢測(cè)工具,可以輕易的發(fā)現(xiàn)內(nèi)存問題,還會(huì)生成更加簡(jiǎn)單清晰的報(bào)告。是一個(gè)開源的檢測(cè)內(nèi)存泄露的庫。 在開發(fā)Android應(yīng)用的過程中如果需要處理圖片或者大量數(shù)據(jù)的時(shí)候,就有可能會(huì)遇到OOM(java.lang.OutOfMemoryError),一般出現(xiàn)最多的是在創(chuàng)建Bitmap上,也有可能是在內(nèi)存中處理了大量的數(shù)據(jù)上。出現(xiàn)OOM應(yīng)用會(huì)直接崩潰,即使沒有...

    shixinzhang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<