android開發中的java記憶體泄露分析

來源:互聯網
上載者:User

做了較長時間的android開發了,發現其實android應用開發入門容易,但是進階或者成為進階工程師,需要具備的基礎能力還是非常高的:效能最佳化、記憶體泄露、apk瘦身、熱修複等等,這些都非常的考驗一個人的能力。android成長之路還很長,自己會持續的走下去。本文主要介紹android記憶體泄露方面的知識。其實要真的理解記憶體泄露,需要對JVM、java語言有一定的瞭解,在這個基礎上就比較容易理解本文了。

一.記憶體泄露概念

在java中,如果一個對象沒有可用價值了,但又被其他引用所指向,那麼這個對象對於gc來說就不是一個垃圾, 所以不會對其進行回收,但是我們認為這應該是個垃圾,應該被gc回收的。這個對象得不到gc的回收, 就會一直存活在堆記憶體中,佔用記憶體,就跟我們說的霸著茅坑不拉屎的道理是一樣的。這樣就導致了記憶體的泄露。

為什麼會記憶體泄露呢,根本原因就是一個永遠不會被使用的對象,因為一些引用沒有斷開,沒有滿足GC條件,導致不會被回收,這就造成了記憶體泄露。比如在Activity中註冊了一個廣播接收器,但是在頁面關閉的時候進行unRegister,就會出現記憶體溢出的現象。如果我們的java運行很久,而這種記憶體泄露不斷的發生,最後就沒記憶體可用了,最終就是我們看到的OOM錯誤。雖然android的記憶體泄露做到了應用程式層級的泄露(android中的每個應用程式都是獨立運行在單獨進程中的,每個應用進程都由虛擬機器指定了一個記憶體上限值,一旦記憶體佔用值超過這個上限值,就會發生oom錯誤,進程被強制kill掉,kill掉的進程記憶體會被系統回收),但是對於一名開發工程師,絕對不能放過任何的記憶體泄露。

二.出現記憶體泄露的場合及解決方案

1.activity中handler間斷的post訊息,會造成activity泄露

1.1出現場合:

     {    Handler mLeakyHandler =  Handler() {          (Message msg) {          }  }      (Bundle savedInstanceState) {    .onCreate(savedInstanceState);        mLeakyHandler.postDelayed( Runnable() {              () { }    },  *  * );  }}

1.2原因分析:

當這個Activity被finished後,延時發送的訊息會繼續在主線程的訊息佇列中存活10分鐘,直到他們被處理。這個訊息持有這個Activity的Handler引用,這個Handler有隱式地持有他的外部類(在這個例子中是SampleActivity)。直到訊息被處理前,這個引用都不會被釋放。因此Activity不會被記憶體回收機制回收,泄露他所持有的應用程式資源。注意,第15行的匿名Runnable類也一樣。匿名類的非靜態執行個體持有一個隱式的外部類引用,因此context將被泄露。

具體的引用順序:

MessageQueue->Message->Runnable->Handler->Activity。所以這就導致當前activity與MessageQueue一直有關聯,導致LeakActivity的對象不能被gc回收,從而導致記憶體泄露。

1.3解決方案:

為瞭解決這個問題,Handler的子類應該定義在一個新檔案中或使用靜態內部類。靜態內部類不會隱式持有外部類的引用。所以不會導致它的Activity泄露。如果你需要在Handle內部調用外部Activity的方法,那麼讓Handler持有一個Activity的弱引用(WeakReference)以便你不會意外導致context泄露。為瞭解決我們執行個體化匿名Runnable類可能導致的記憶體泄露,我們將用一個靜態變數來引用他(因為匿名類的靜態執行個體不會隱式持有他們外部類的引用)。

     {           Runnable sRunnable =  Runnable() {                          () {            }        };      MyHandler mHandler =  MyHandler();          (Bundle savedInstanceState) {        .onCreate(savedInstanceState);                mHandler.postDelayed(sRunnable,  *  * );                finish();    }              {          WeakReference<SampleActivity> mActivity;         (SampleActivity activity) {            mActivity =  WeakReference<SampleActivity>(activity);        }                  (Message msg) {            SampleActivity activity = mActivity.get();             (activity != ) {                            }        }    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.