Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android系統教程 >> Android開發教程 >> android開發中的java內存洩露分析

android開發中的java內存洩露分析

編輯:Android開發教程

做了較長時間的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 != ) {
                
            }
        }
    }
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved