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

內(nèi)存泄漏:

指 程序在申請內(nèi)存后,當(dāng)該內(nèi)存不需再使用 但卻無法被釋放,歸還給程序的現(xiàn)象。

內(nèi)存溢出

是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory

android常見內(nèi)存泄漏

1.Handler 引起的內(nèi)存泄漏
2.單例模式引起的內(nèi)存泄漏
3.非靜態(tài)內(nèi)部類創(chuàng)建靜態(tài)實例引起的內(nèi)存泄漏
4.非靜態(tài)匿名內(nèi)部類引起的內(nèi)存泄漏
5.注冊/反注冊未成對使用引起的內(nèi)存泄漏
6.資源對象沒有關(guān)閉引起的內(nèi)存泄漏
7.集合對象沒有及時清理引起的內(nèi)存泄漏

優(yōu)化內(nèi)存泄漏

1、Handler持有的引用最好使用弱引用,在Activity被釋放的時候要記得清空Message,取消Handler對象的Runnable;
2、非靜態(tài)內(nèi)部類、非靜態(tài)匿名內(nèi)部類會自動持有外部類的引用,為避免內(nèi)存泄露,可以考慮把內(nèi)部類聲明為靜態(tài)的;
3、對于生命周期比Activity長的對象,要避免直接引用Activity的context,可以考慮使用ApplicationContext;
4、廣播接收器、EventBus等的使用過程中,注冊/反注冊應(yīng)該成對使用;
5、不再使用的資源對象Cursor、File、Bitmap等要記住正確關(guān)閉;
6、集合里面的東西、有加入就應(yīng)該對應(yīng)有相應(yīng)的刪除

如何檢測內(nèi)存泄漏

1,在Android studio3.0以前,在下邊有一個Android Monitor,在Android studio3.0以后,將其改為了Android profiler,里邊可以分析CPU使用率,內(nèi)存、包括網(wǎng)絡(luò)狀態(tài),一般檢測內(nèi)存泄漏,只需要點擊memory,然后確保移動端啟動的程序和studio工具正確連接,如果要檢測當(dāng)前頁面是否存在泄漏問題,只需要將該activity finish,然后底部有一個小垃圾桶,他是起到手動觸發(fā)gc的功能,通過手動回收,然后再去包下查看該應(yīng)用當(dāng)前存留的實例,如果剛剛finish并且gc的activity仍然存在,證明在這個activity當(dāng)中存在內(nèi)存泄漏。點擊額外生成的activity(一般是后邊帶有$這個符號),一般在studio右邊會有泄漏原因的提示,當(dāng)然具體位置還需要程序員通過經(jīng)驗判斷,主動到項目業(yè)務(wù)中查詢。

2,可以使用leakcanary框架,這個相對比較簡單,只需要添加依賴,在application啟動的時候,判斷是否有l(wèi)eakcanary對該進(jìn)程泄漏的監(jiān)聽,如果沒有,在程序啟動的時候安裝leakcanary即可

內(nèi)存溢出原因

內(nèi)存溢出就是內(nèi)存不夠,引起內(nèi)存溢出的原因有很多種,常見的有以下幾種:
1、內(nèi)存中加載的數(shù)據(jù)量過于龐大,如一次從數(shù)據(jù)庫取出過多數(shù)據(jù);
2、集合類中有對對象的引用,使用完后未清空,使得JVM不能回收;
3、代碼中存在死循環(huán)或循環(huán)產(chǎn)生過多重復(fù)的對象實體;
4、使用的第三方軟件中的BUG;
5、啟動參數(shù)內(nèi)存值設(shè)定的過?。?/p>

內(nèi)存溢出解決方法

【情況一】:

java.lang.OutOfMemoryError:Javaheapspace:

這種是java堆內(nèi)存不夠,一個原因是真不夠(如遞歸的層數(shù)太多等),另一個原因是程序中有死循環(huán);
如果是java堆內(nèi)存不夠的話,可以通過調(diào)整JVM下面的配置來解決:

-Xms3062m
 -Xmx3062m</pre>

【情況二】

java.lang.OutOfMemoryError:GCoverheadlimitexceeded

【解釋】:JDK6新增錯誤類型,當(dāng)GC為釋放很小空間占用大量時間時拋出;一般是因為堆太小,導(dǎo)致異常的原因,沒有足夠的內(nèi)存。
  【解決方案】:
  1、查看系統(tǒng)是否有使用大內(nèi)存的代碼或死循環(huán);
  2、通過添加JVM配置,來限制使用內(nèi)存:

    -XX:-UseGCOverheadLimit</pre>

【情況三】:

java.lang.OutOfMemoryError:PermGenspace:

這種是P區(qū)內(nèi)存不夠,可通過調(diào)整JVM的配置:
  -XX:MaxPermSize=128m
  -XXermSize=128m
  【注】:
  JVM的Perm區(qū)主要用于存放Class和Meta信息的,Class在被Loader時就會被放到PermGenspace,這個區(qū)域成為年老代,GC在主程序運行期間不會對年老區(qū)進(jìn)行清理,
  默認(rèn)是64M大小,當(dāng)程序需要加載的對象比較多時,超過64M就會報這部分內(nèi)存溢出了,需要加大內(nèi)存分配,一般128m足夠

【情況四】:

java.lang.OutOfMemoryError:Directbuffermemory

調(diào)整-XX:MaxDirectMemorySize=參數(shù),
如添加JVM配置:

   -XX:MaxDirectMemorySize=128m</pre>

【情況五】:

java.lang.OutOfMemoryError:unabletocreatenewnativethread

【原因】:Stack空間不足以創(chuàng)建額外的線程,要么是創(chuàng)建的線程過多,要么是Stack空間確實小了。
【解決】:由于JVM沒有提供參數(shù)設(shè)置總的stack空間大小,但可以設(shè)置單個線程棧的大?。欢到y(tǒng)的用戶空間一共是3G,除了Text/Data/BSS/MemoryMapping幾個段之外,Heap和Stack空間的總量有限,是此消彼長的。因此遇到這個錯誤, 可以通過兩個途徑解決:

1.通過-Xss啟動參數(shù)減少單個線程棧大小,這樣便能開更多線程(當(dāng)然不能太小,太小會出現(xiàn)StackOverflowError);
2.通過-Xms-Xmx兩參數(shù)減少Heap大小,將內(nèi)存讓給Stack(前提是保證Heap空間夠用)。

【情況六】:
java.lang.StackOverflowError

【原因】:這也內(nèi)存溢出錯誤的一種,即線程棧的溢出,要么是方法調(diào)用層次(比如存在無限遞歸調(diào)用),要么是線程棧太小。
【解決】:優(yōu)化程序設(shè)計,減少方法調(diào)用層次;調(diào)整-Xss參數(shù)增加線程棧大小</pre>

最后編輯于
?著作權(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)容