今天我們來學習Android內存泄漏方面的知識,Java內存泄漏的基礎知識、Android中的常見內存泄漏。
一、java內存泄漏的基礎知識
1、java 內存的分配策略
- 靜態存儲區: 存放全局變量和靜態數據,在整個程序運行期間都存在;
- 棧區:存放方法體內的基本類型的數據和對象的引用(對象本身存儲在堆區),會在棧區分配內存空間,並在方法執行結束後會自動釋放該變量所分配的內存空間;
- 堆區:存放動態產生的數據,new出來的對象和數組,在堆區分配的內存由java回收器進行管理;
2、java 內存泄漏的原因
無用/不再使用的的對象持續佔有內存,內存得不到及時釋放,造成內存空間的浪費。
二、Android中的常見內存泄漏
1、單例造成的內存泄漏:
原因:單例持有的context導致Activity無法回收;
解決:context = context.getApplicationContext();
2、匿名內部類造成的內存泄漏:
原因: 非靜態內部類持有外部類的引用;
解決: 內部類設爲靜態內部類;
3、Handler造成的內存泄漏:
原因:非靜態內部類持有外部類的引用,導致Activity無法回收;
解決:
1)、Handler設爲靜態內部類;
2)、持有的context對象包裝成弱引用;
3)、在Activity 的 onDestroy() 方法中調用 Handler.removeCallbacksAndMessages(null) 移除Handler 所有回調和信息;
4、AsyncTask造成的內存泄露:
原因:非靜態內部類持有外部類的引用,導致Activity無法回收;
解決:
1)、AsyncTask設爲靜態內部類;
2)、持有的context對象包裝成弱引用;
3)、在Activityd的onDestroy()方法中調用 AsyncTask.cancel() 取消任務。
5、資源未關閉造成的內存泄漏:
原因: Socket、Broadcast、Cursor、Bitmap等,使用完未及時關閉;
解決:資源使用完及時關閉釋放;
6、避免使用static變量:
原因:佔用內存,一般不會被回收;static的生命週期跟app生命週期一致,在系統不夠內存情況下會自動回收靜態內存,這樣就會引起訪問全局靜態錯誤;
解決:減少使用;