欧美日韩不卡一区二区三区,www.蜜臀.com,高清国产一区二区三区四区五区,欧美日韩三级视频,欧美性综合,精品国产91久久久久久,99a精品视频在线观看

解決方法

Android內(nèi)存泄漏終極解決方法介紹

時(shí)間:2021-04-07 12:03:18 解決方法 我要投稿

Android內(nèi)存泄漏終極解決方法介紹

  一、概述

  在 Android內(nèi)存泄漏終極解決篇(上)中我們介紹了如何檢查一個(gè)App是否存在內(nèi)存泄漏的問題,本篇將總結(jié)典型的內(nèi)存泄漏的代碼,并給出對(duì)應(yīng)的解決方案。內(nèi)存泄漏的主要問題可以分為以下幾種類型:

  靜態(tài)變量引起的內(nèi)存泄漏 非靜態(tài)內(nèi)部類引起的內(nèi)存泄漏 資源未關(guān)閉引起的內(nèi)存泄漏

  二、靜態(tài)變量引起的內(nèi)存泄漏

  在java中靜態(tài)變量的生命周期是在類加載時(shí)開始,類卸載時(shí)結(jié)束。換句話說,在android中其生命周期是在進(jìn)程啟動(dòng)時(shí)開始,進(jìn)程死亡時(shí)結(jié)束。所以在程序的運(yùn)行期間,如果進(jìn)程沒有被殺死,靜態(tài)變量就會(huì)一直存在,不會(huì)被回收掉。如果靜態(tài)變量強(qiáng)引用了某個(gè)Activity中變量,那么這個(gè)Activity就同樣也不會(huì)被釋放,即便是該Activity執(zhí)行了onDestroy(不要將執(zhí)行onDestroy和被回收劃等號(hào))。這類問題的解決方案為:1.尋找與該靜態(tài)變量生命周期差不多的替代對(duì)象。2.若找不到,將強(qiáng)引用方式改成弱引用。比較典型的例子如下:

  單例引起的Context內(nèi)存泄漏

  public class IMManager { private Context context; private static IMManager mInstance; public static IMManager getInstance(Context context) { if (mInstance == null) { synchronized (IMManager.class) { if (mInstance == null) mInstance = new IMManager(context); } } return mInstance; } private IMManager(Context context) { this.context = context; }}

  當(dāng)調(diào)用getInstance時(shí),如果傳入的context是Activity的'context。只要這個(gè)單例沒有被釋放,這個(gè)Activity也不會(huì)被釋放。

  解決方案

  傳入Application的context,因?yàn)锳pplication的context的生命周期比Activity長,可以理解為Application的context與單例的生命周期一樣長,傳入它是最合適的。

  public class IMManager { private Context context; private static IMManager mInstance; public static IMManager getInstance(Context context) { if (mInstance == null) { synchronized (IMManager.class) { if (mInstance == null) //將傳入的context轉(zhuǎn)換成Application的context mInstance = new IMManager(context.getApplicationContext()); } } return mInstance; } private IMManager(Context context) { this.context = context; }}

  三、非靜態(tài)內(nèi)部類引起的內(nèi)存泄漏

  在java中,創(chuàng)建一個(gè)非靜態(tài)的內(nèi)部類實(shí)例,就會(huì)引用它的外圍實(shí)例。如果這個(gè)非靜態(tài)內(nèi)部類實(shí)例做了一些耗時(shí)的操作,就會(huì)造成外圍對(duì)象不會(huì)被回收,從而導(dǎo)致內(nèi)存泄漏。這類問題的解決方案為:1.將內(nèi)部類變成靜態(tài)內(nèi)部類 2.如果有強(qiáng)引用Activity中的屬性,則將該屬性的引用方式改為弱引用。3.在業(yè)務(wù)允許的情況下,當(dāng)Activity執(zhí)行onDestory時(shí),結(jié)束這些耗時(shí)任務(wù)。

  內(nèi)部線程造成的內(nèi)存泄漏

  public class LeakAty extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.aty_leak); test(); } public void test() { //匿名內(nèi)部類會(huì)引用其外圍實(shí)例LeakAty.this,所以會(huì)導(dǎo)致內(nèi)存泄漏 new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } }

  解決方案

  將非靜態(tài)匿名內(nèi)部類修改為靜態(tài)匿名內(nèi)部類

  public class LeakAty extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.aty_leak); test(); } //加上static,變成靜態(tài)匿名內(nèi)部類 public static void test() { new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); }}

  Handler引起的內(nèi)存泄漏

  public class LeakAty extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.aty_leak); fetchData(); } private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case 0: // 刷新數(shù)據(jù) break; default: break; } }; }; private void fetchData() { //獲取數(shù)據(jù) mHandler.sendEmptyMessage(0); }}

  mHandler 為匿名內(nèi)部類實(shí)例,會(huì)引用外圍對(duì)象LeakAty.this,如果該Handler在Activity退出時(shí)依然還有消息需要處理,那么這個(gè)Activity就不會(huì)被回收。

  解決方案

  public class LeakAty extends Activity { private TextView tvResu< private MyHandler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.aty_leak); tvResult = (TextView) findViewById(R.id.tvResult); handler = new MyHandler(this); fetchData(); } //第一步,將Handler改成靜態(tài)內(nèi)部類。 private static class MyHandler extends Handler { //第二步,將需要引用Activity的地方,改成弱引用。 private WeakReferenceatyInstance; public MyHandler(LeakAty aty) { this.atyInstance = new WeakReference(aty); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); LeakAty aty = atyInstance == null ? null : atyInstance.get(); //如果Activity被釋放回收了,則不處理這些消息 if (aty == null||aty.isFinishing()) { return; } aty.tvResult.setText("fetch data success"); } } private void fetchData() { // 獲取數(shù)據(jù) handler.sendEmptyMessage(0); } @Override protected void onDestroy() { //第三步,在Activity退出的時(shí)候移除回調(diào) super.onDestroy(); handler.removeCallbacksAndMessages(null); }}

  四、資源未關(guān)閉引起的內(nèi)存泄漏

  當(dāng)使用了BraodcastReceiver、Cursor、Bitmap等資源時(shí),當(dāng)不需要使用時(shí),需要及時(shí)釋放掉,若沒有釋放,則會(huì)引起內(nèi)存泄漏。

  綜上所述,內(nèi)存泄漏的主要情況為上面的三大類型,最終歸結(jié)為一點(diǎn),就是資源在不需要的時(shí)候沒有被釋放掉。所以在編碼的過程中要注意這些細(xì)節(jié),提高程序的性能。

【Android內(nèi)存泄漏終極解決方法介紹】相關(guān)文章:

關(guān)于PHPExcel內(nèi)存泄漏問題解決方法06-25

內(nèi)存卡讀不出來終極解決方法08-07

如何識(shí)別Java中的內(nèi)存泄漏09-10

如何解決java內(nèi)存泄漏11-01

C語言中的指針和內(nèi)存泄漏10-05

如何解決java內(nèi)存泄漏的問題08-19

Windows內(nèi)存出錯(cuò)的解決方法02-05

Windows內(nèi)存出錯(cuò)的解決方法10-08

Java內(nèi)存溢出的解決方法12-03