內(nèi)存溢出(out of memory)
OOM指當前對象的內(nèi)存占用已經(jīng)超出分配內(nèi)存的大小,這時未處理的異常就會拋出芝发。過多的內(nèi)存泄露會導致內(nèi)存溢出,造成程序崩潰
造成內(nèi)存溢出的原因:
1.內(nèi)存泄漏導致苛谷;2.占用內(nèi)存比較多的對象
如常見的內(nèi)存溢出:
bitmap過大(顯示像素過高或者圖片尺寸遠遠大于顯示空間尺寸時辅鲸。通常要將bitmap縮放,減少暫占用內(nèi)存)腹殿;
引用沒釋放(長時間保持某些資源的引用独悴,導致GC(garbage collection垃圾回收)無法回收例书,該對象占用的內(nèi)存就無法被使用。如activity被引用刻炒,在調(diào)用finish()之后卻沒有釋放决采,第二次打開又重新創(chuàng)建,這樣的內(nèi)存泄露不斷發(fā)生坟奥,就會導致內(nèi)存的溢出)树瞭;
資源對象沒關閉(Cursor/file等資源,會在finalize中關閉爱谁,但效率過低晒喷,易造成內(nèi)存泄漏;SQLiteCurost當數(shù)據(jù)量大的時候容易泄漏)访敌;
內(nèi)存泄漏(memory leak)
有一些對象只有有限的生命周期厨埋。當它們的任務完成了之后,將會被GC回收捐顷。如果在對象的生命周期本該結束的時候荡陷,還被一系列的引用,就會導致內(nèi)存泄漏迅涮。隨著泄漏的累積废赞,app將消耗完內(nèi)存。
如Activity.onDestory()被調(diào)用之后叮姑,view樹和bitmap應該都被GC回收唉地。如果一個正在運行的后臺線程繼續(xù)持有這個activity的引用,那么相關的內(nèi)存將不會被回收传透,最終導致out OfMemoryError崩潰耘沼。
memory leak最終會導致OOM
內(nèi)存泄漏的原因:
1.資源對象沒關閉、集合類內(nèi)存泄漏(資源對象沒關閉:Cursor/file等資源朱盐,會在finalize中關閉群嗤,但效率過低,易造成內(nèi)存泄漏兵琳;SQLiteCurost當數(shù)據(jù)量大的時候容易泄漏)狂秘,屬性動畫在activity onDestory()的時候 animator.cancel()來停止動畫
2.使用adapter時沒有使用系統(tǒng)緩存的converview
3.沒有及時調(diào)用recycle()釋放不再使用的bitmap(釋放之后建議bitmap= null;避免GC回收過慢等原因)
4.上下文的context用的是activity或者fragment。因此要使用application的context來代替activity相關的context躯肌,否則會在activity者春、fragment銷毀時也不會銷毀其內(nèi)存(不要讓生命周期長于activity的對象持有activity的引用)
在以下情況下不可以使用application
a.對話框創(chuàng)建的上下文
b.跳轉(zhuǎn)到其它activity的上下文
c.創(chuàng)建布局layout或view要用到的上下文
5.廣播注冊沒取消造成的內(nèi)存泄漏
6.handler應該申請為static對象,并且在內(nèi)部類中保存一個對外部類的弱引用
內(nèi)存泄漏的分類:
1.常發(fā)性內(nèi)存泄漏:發(fā)生內(nèi)存泄漏的代碼會被多次執(zhí)行清女,每次執(zhí)行都會導致一塊內(nèi)存泄漏
2.偶發(fā)性內(nèi)存泄漏:發(fā)生內(nèi)存泄漏的代碼只有在特定環(huán)境或操作過程中才會發(fā)生钱烟。常發(fā)性和偶發(fā)性是相對的。對于特定的環(huán)境,偶發(fā)性可能會變成常發(fā)性拴袭。因此測試環(huán)境和測試方法對檢測內(nèi)存泄漏尤其重要
3.一次性內(nèi)存泄漏:發(fā)生內(nèi)存泄漏的代碼只會執(zhí)行一次传惠,或者由于算法上的缺陷,導致總有一塊僅且有一塊內(nèi)存發(fā)生泄漏稻扬。如在類的構造函數(shù)中分配內(nèi)存,在析構函數(shù)中卻沒有釋放該內(nèi)存,導致內(nèi)存泄漏只會發(fā)生一次
4.隱私內(nèi)存泄漏:程序在運行過程中不停地分配內(nèi)存。但是在結束的時候才釋放內(nèi)存讨跟。嚴格來說并沒有發(fā)生內(nèi)存泄漏使碾,因為程序最終還是釋放了所有的內(nèi)存。但是對于一個服務程序徘禁。需要運行幾天甚至幾個月。不及時釋放內(nèi)存也可能導致最終耗盡所有的內(nèi)存。稱這種內(nèi)存泄漏為隱私內(nèi)存泄漏
內(nèi)存泄漏和內(nèi)存溢出都不能通過try catch處理
內(nèi)存泄漏的檢測工具:leakcanary
參考來源