內(nèi)存溢出和內(nèi)存泄漏

內(nèi)存溢出 out of memory,是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory;比如申請了一個integer,但給它存了long才能存下的數(shù),那就是內(nèi)存溢出。

內(nèi)存泄露 memory leak,是指程序在申請內(nèi)存后,無法釋放已申請的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很嚴(yán)重,無論多少內(nèi)存,遲早會被占光。

memory leak會最終會導(dǎo)致out of memory!

一,常見的內(nèi)存溢出情況:
1,加載圖片過大,超出所申請的內(nèi)存
解決方法:

(1)對圖片進行壓縮處理(不推薦,圖片多起來,你再怎么壓縮也是要耗很大的內(nèi)存)

(2)使用第三方加載圖片框架(推薦,開源,省時又省事)Glide ,Picasso ,Fresco等

(3)減少Bitmap對象的引用,并及時的回收

2,對象引用沒及時回收,導(dǎo)致堆積,超出所申請的內(nèi)存
解決方法:

(1)動態(tài)回收內(nèi)存

(2)對像引用采用軟引用(方便內(nèi)能夠?qū)Υ诉M行回收)

(3)對象復(fù)用,存在的對象不要重復(fù)多次new它,應(yīng)該循環(huán)利用

(4)注意對象復(fù)用的生命周期(static和程序進程一樣長)

(5)單例模式的合理使用,單例模式避免重復(fù)創(chuàng)建對象,但也注意他的生命周期和程序進程一樣長容易因為持有的對象沒有正?;厥諏?dǎo)致內(nèi)存泄漏

(6)監(jiān)聽器不使用時及時注銷

(7)盡量減少抽象對象的使用

3,頁面持有內(nèi)存,沒有及時回收
(1)Activity,fragment頁面:

    1.Acitvity對靜態(tài)變量的持有問題

    2.頁面回收時及時回收Handler消息隊列

    3.Activity Context 被其他實例持有,導(dǎo)致無法GC

(2)webview頁面

    1.及時銷毀webView 避免存在進程對內(nèi)存進行消耗

4,無用服務(wù)后臺持續(xù)運作,占用過多內(nèi)存
(1)用完及時關(guān)閉

二,常見的內(nèi)存泄漏情況:
1,Handler 引發(fā)內(nèi)存泄漏
(1)handler發(fā)送的Message未被處理,那么該Message及發(fā)送它的Handler對象都會被線程一直持有,由于Handler屬于TLS(Thread Local Storage)變量,生命周期和Activity是不一致的。如果Handler是我們的Activity類的非靜態(tài)內(nèi)部類,Handler就會持有Acitvity的強引用,此時該Activity退出時無法進行內(nèi)存回收,造成內(nèi)存泄漏。

解決方法:

將Handler聲明為靜態(tài)內(nèi)部類和軟引用,這樣它就不會持有外部類的引用了,Handler的生命周期就與Activity無關(guān)了。聲明時context采用Application的Context,銷毀Acitvity時處理掉隊列中的消息。

2,單例模式引發(fā)內(nèi)存泄漏
(1)單例模式的靜態(tài)屬性,使它的生命周期和應(yīng)用一樣長,如果讓單例引用Activity的強引用,Activity無法gc,就會導(dǎo)致內(nèi)存泄漏。

解決方法:

所以在創(chuàng)建單例時,構(gòu)造函數(shù)里對Activity 的context引用換成 ApplicationContext

3,匿名內(nèi)部類引起內(nèi)存泄漏
(1)activity ,fragment 或者view中使用匿名類,匿名類對象會持有Activity,F(xiàn)ragment,View的引用,如果引用傳到異步線程中,異步線程和Activityt生命周期不一致的時候,就會造成Activity的泄漏。

解決方法:能直接聲明內(nèi)部類引用就減少匿名內(nèi)部類的引用。盡量不把匿名內(nèi)部類用到異步線程中去

4,WebView 引起的內(nèi)存泄漏
(1)webview解析網(wǎng)頁時會申請Natvie堆內(nèi)存用于保存頁面元素,當(dāng)頁面較復(fù)雜時,會有很大的內(nèi)存占用。如果包含圖片,內(nèi)存占用會更嚴(yán)重,并且打開新頁面時,為了能快速回退,之前頁面內(nèi)存也不會釋放。或者是退出Activity頁面時,webview還在處理網(wǎng)絡(luò)數(shù)據(jù),持有Activity的引用時會導(dǎo)致Activity不能被Gc也會造成內(nèi)存泄漏。

解決方法:

webview采用動態(tài)添加,onDestroy時移除,和銷毀webview。

5,集合引發(fā)的內(nèi)存泄漏
(1)把對象的引用加入集合容器中,當(dāng)我們不再需要該對象時,并沒有把它的引用從集合中清理掉,當(dāng)集合中的內(nèi)容過大的時候,并且是static的時候就造成了內(nèi)存泄漏。

解決方法:

在onDestory中清空;

6,其他引發(fā)內(nèi)存泄漏
(1)構(gòu)造Adapter時,沒有使用緩存的convertView

(2)Bitmap在不使用的時候沒有使用recycle()釋放內(nèi)存

(3)線程未終止造成內(nèi)存泄漏

(4)對象的注冊與反注冊沒有成對出現(xiàn)造成的內(nèi)存泄漏;比如注冊廣播接收器,注冊觀察者等

(5)不要在執(zhí)行頻率很高的方法或者循環(huán)中創(chuàng)建對象。


本文整理自以下兩篇文章
原文鏈接:https://blog.csdn.net/lililijunwhy/article/details/87966337
原文鏈接:https://blog.csdn.net/sasafeng/article/details/8559992

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容