Android App 記憶體泄露之Thread

來源:互聯網
上載者:User

Android App 記憶體泄露之Thread

Thread 記憶體泄露
線程也是造成記憶體泄露的一個重要的源頭。線程產生記憶體泄露的主要原因在於線程生命週期的不可控。
1.看一下下面是否存在問題
 /** *  * @version 1.0.0  * @author Abay Zhuang 
* Create at 2014-7-17 */public class ThreadActivity extends Activity {public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);new MyThread().start();}private class MyThread extends Thread {@Overridepublic void run() {super.run();dosomthing();}}private void dosomthing(){}}



這段代碼很平常也很簡單,是我們經常使用的形式。
真的沒有問題嗎
我們思考一個問題:假設MyThread的run函數是一個很費時的操作,當我們開啟該線程後,將裝置的橫屏變為了豎屏,一般情況下當螢幕轉換時會重新建立Activity,按照我們的想法,老的Activity應該會被銷毀才對,然而事實上並非如此。由於我們的線程是Activity的內部類,所以MyThread中儲存了Activity的一個引用,當MyThread的run函數沒有結束時,MyThread是不會被銷毀的,因此它所引用的老的Activity也不會被銷毀,因此就出現了記憶體泄露的問題。   
2.這種線程導致的記憶體泄露問題應該如何解決呢?
  • 第一、將線程的內部類,改為靜態內部類。
  • 第二、線上程內部採用弱引用儲存Context引用。 代碼如下:

    /** *  * @version 1.0.0 * @author Abay Zhuang 
    * Create at 2014-7-17 */public class ThreadAvoidActivity extends Activity {public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);new MyThread(this).start();}private void dosomthing() {}private static class MyThread extends Thread {WeakReference mThreadActivityRef;public MyThread(ThreadAvoidActivity activity) {mThreadActivityRef = new WeakReference(activity);}@Overridepublic void run() {super.run();if (mThreadActivityRef == null)return;if (mThreadActivityRef.get() != null)mThreadActivityRef.get().dosomthing();// dosomthing}}}


    上面的兩個步驟其實是切換兩個對象的雙向強引用連結
      
    1. 靜態內部類:切斷Activity 對於 MyThread的強引用。
    2. 弱引用: 切斷MyThread對於Activity 的強引用。3.AsynTask 內部類會如何呢?
      有些人喜歡用Android提供的AsyncTask,但事實上AsyncTask的問題更加嚴重,Thread只有在run函數不結束時才出現這種記憶體泄露問題,然而AsyncTask內部的實現機制是運用了ThreadPoolExcutor,該類產生的Thread對象的生命週期是不確定的,是應用程式無法控制的,因此如果AsyncTask作為Activity的內部類,就更容易出現記憶體泄露的問題。

      代碼如下:

      /** *  * 弱引用 * @version 1.0.0  * @author Abay Zhuang 
      * Create at 2014-7-17 */public abstract class WeakAsyncTask extends AsyncTask {protected WeakReference mTarget;public WeakAsyncTask(WeakTarget target) { mTarget = new WeakReference(target);}@Overrideprotected final void onPreExecute() { final WeakTarget target = mTarget.get(); if (target != null) { this.onPreExecute(target); }}@Overrideprotected final Result doInBackground(Params... params) { final WeakTarget target = mTarget.get(); if (target != null) { return this.doInBackground(target, params); } else { return null; }}@Overrideprotected final void onPostExecute(Result result) { final WeakTarget target = mTarget.get(); if (target != null) { this.onPostExecute(target, result); }}protected void onPreExecute(WeakTarget target) { // Nodefaultaction}protected abstract Result doInBackground(WeakTarget target, Params... params);protected void onPostExecute(WeakTarget target, Result result) { // Nodefaultaction}}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.