老李分享:Android性能优化之内存泄漏 3
線程造成的內存泄漏
對于線程造成的內存泄漏,也是平時比較常見的,如下這兩個示例可能每個人都這樣寫過:
?
//——————test1
??????? new AsyncTask<Void, Void, Void>() {
??????????? @Override
??????????? protected Void doInBackground(Void... params) {
??????????????? SystemClock.sleep(10000);
??????????????? return null;
??????????? }
??????? }.execute();
//——————test2
??????? new Thread(new Runnable() {
? ??????????@Override
??????????? public void run() {
??????????????? SystemClock.sleep(10000);
??????????? }
??????? }).start();
上面的異步任務和Runnable都是一個匿名內部類,因此它們對當前Activity都有一個隱式引用。如果Activity在銷毀之前,任務還未完成,?
那么將導致Activity的內存資源無法回收,造成內存泄漏。正確的做法還是使用靜態內部類的方式,如下:
static class MyAsyncTask extends AsyncTask<Void, Void, Void> {
??????? private WeakReference<Context> weakReference;
?
??????? public MyAsyncTask(Context context) {
??????????? weakReference = new WeakReference<>(context);
??????? }
?
??????? @Override
?? ?????protected Void doInBackground(Void... params) {
??????????? SystemClock.sleep(10000);
??????????? return null;
??????? }
?
??????? @Override
??????? protected void onPostExecute(Void aVoid) {
??????????? super.onPostExecute(aVoid);
??????????? MainActivity activity = (MainActivity) weakReference.get();
??????????? if (activity != null) {
??????????????? //...
??????????? }
??????? }
??? }
??? static class MyRunnable implements Runnable{
??????? @Override
??????? public void run() {
??????????? SystemClock.sleep(10000);
??????? }
??? }
//——————
??? new Thread(new MyRunnable()).start();
new MyAsyncTask(this).execute();
?
這樣就避免了Activity的內存資源泄漏,當然在Activity銷毀時候也應該取消相應的任務AsyncTask::cancel(),避免任務在后臺執行浪費資源。
資源未關閉造成的內存泄漏
對于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等資源的使用,應該在Activity銷毀時及時關閉或者注銷,否則這些資源將不會被回收,造成內存泄漏。
一些建議
1、對于生命周期比Activity長的對象如果需要應該使用ApplicationContext?
2、在涉及到Context時先考慮ApplicationContext,當然它并不是萬能的,對于有些地方則必須使用Activity的Context,對于Application,Service,Activity三者的Context的應用場景如下:?
?
**其中:**NO1表示Application和Service可以啟動一個Activity,不過需要創建一個新的task任務隊列。而對于Dialog而言,只有在Activity中才能創建?
3、對于需要在靜態內部類中使用非靜態外部成員變量(如:Context、View ),可以在靜態內部類中使用弱引用來引用外部類的變量來避免內存泄漏?
4、對于生命周期比Activity長的內部類對象,并且內部類中使用了外部類的成員變量,可以這樣做避免內存泄漏:
將內部類改為靜態內部類
靜態內部類中使用弱引用來引用外部類的成員變量
5、對于不再需要使用的對象,顯示的將其賦值為null,比如使用完Bitmap后先調用recycle(),再賦為null?
6、保持對對象生命周期的敏感,特別注意單例、靜態對象、全局性集合等的生命周期
轉載于:https://blog.51cto.com/10988776/1729228
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的老李分享:Android性能优化之内存泄漏 3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 怎么防止session 失效
- 下一篇: 使用Go你需要注意的坑在这里!