內存泄漏的產生
Android虛擬機中把內存分為兩部分,一部分為堆空間,里面儲存的是對象的實例,需要開發者主動創建,垃圾回收主要作用在這部分;另一部分為棧空間,儲存一些全局引用和靜態變量等值,該空間的分配與回收由系統機制決定,垃圾回收機制不作用這塊區域。
內存泄漏也稱作“存儲滲漏”,用動態存儲分配函數動態開辟的空間,在使用完畢后未釋放,結果導致一直占據該內存單元。直到程序結束。即所謂內存泄漏。
內存泄漏簡單地說就是申請了一塊內存空間,使用完畢后沒有釋放掉。它的一般表現方式是程序運行時間越長,占用內存越多,最終用盡全部內存,整個系統崩潰。由程序申請的一塊內存,且沒有任何一個指針指向它,那么這塊內存就泄露了。
靜態變量的生命周期基本和應用同周期
(防止)內存泄漏的幾點建議
1、盡量不要用生命周期長于Activity的對象來持有Activity的引用。
2、在需要傳入Context的時候盡量考慮使用Application的Context而不是Activity的
3、在Activity中盡量避免使用生命周期不受控制的非靜態類型的內部類,可以使用靜態類型的內部類加上弱引用的方式實現。
Android應用內存泄漏的的原因有以下幾個:
1、查詢數據庫后沒有關閉游標cursor。
2、 使用Adapter作為適配器時沒有復用convertView。可以參考ListView與BaseAdapter優化。
3、bitmap沒有回收, Bitmap對象不在使用時調用recycle()釋放內存。可以參考Bitmap相關:管理Bitmap內存。
4、注冊對象后沒有反注冊,比如Broadcast Receiver等。
5、handler問題,如果handler是非靜態的,會導致Activity或者Service不被回收,所以應當注冊為靜態內部類,同時在onDestroy時停止線程:mThread.getLooper().quit();
6 、對象被生命周期長的對象引用,如activity被靜態集合引用導致activity不能釋放,Activity被靜態引用,特別是緩存bitmap時,解決方法可以考慮使用Application的context代替Activity的context。
7、WebView的泄露問題:在魅族上面發現webView打開再關閉就會內存泄露..目前使用的解決方法是在webview外面嵌套一層layout作為 container,在Activity的onDestroy中調用container.removeAllViews()方法。
8、Dialog導致Window泄露,如果需要在dialog依附的Activity銷毀前沒有調用dialog.dismiss().會導致Activity泄露
檢測內存泄露的方法
Android Studio 自帶的 Memory Monitor,手動觸發GC可以看得比較直觀,但是dump出來的文件需要處理才能用MAT打開,利用 sdk/platforms-tool/ 下的 hprof-conv 文件,命令為: /hprof-conv source output
內存泄漏如何解決
通過內存分析工具 MAT(Memory Analyzer Tool),找到內存泄露的對象