Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 內存洩露 分析

Android 內存洩露 分析

編輯:關於Android編程

實際開發中發現Android內存洩露問題很容易發生,下面大致是一些常犯的問題,希望大家引以為戒:

一、注冊廣播監聽器,忘記反注冊。

registerReceiver(mReceiver, intentFilter)

unRegisterReceiver(mReceiver, intentFilter)

這兩者出現的位置如下:

onCreate ------ onDestroy

onResume ------ onPause

onStart ------ onStop

千萬不要放錯哦,不然會有問題。

二、其他類型監聽器,比如監聽電話狀態:

在android.telephony.TelephonyManager.java中,提供了一個監聽電話狀態的接口:

public void listen(PhoneStateListener listener, int events) {

Xxxxxx;//

}

這個方法經常北使用,如果你在activity裡面使用了這個接口,記得在activity destroy的時候將其反注冊啊。

如何反注冊呢?是unListen麼?不是的,看源碼注釋:

/* To unregister a listener, pass the listener object and set the

* events argument to

* {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).

*/

所以你只需要在相應位置再次調用listen接口,將listener這個參數值傳遞成PhoneStateListener#LISTEN_NONE LISTEN_NONE就可以了。

三、檢查你的acrtivity被應用的情況,主要包括:

1.是否被被Application引用

Application在android應用中屬於長生命周期對象,如果你的activity需要被回收,但是此時卻被application引用,那麼會導致activity無法被順利回收了。

2.是否被activity中內部類引用

普通內部類會持有對外部類對象的引用,如果你的內部類對象在從事一個耗時的操作,這個時候如果想回收外部類對象的話,需要先停止內部類對象正在做的操作。

靜態內部類不會持有對外部類對象的引用,可以解決這個問題。

3.是否有被靜態引用

你是否也寫過這種傻傻的事情,在一個類中寫上了對一個activity的靜態引用,

比如 private static XActivity activity = XActivity.getInstance();

你想想,如果你這麼寫了,你在退出這個XActivity的時候它可以有效的釋放麼?

你需要考慮如何先取消這個引用才可以,對吧。

四.注意重型對象,即占用內存比較多的對象,比如bitmap對象。這類對象在不用的時候要手動回收。

簡單總結一下:

Java世界的內存洩露問題基本都是一類:一個對象在需要釋放的時候還在被別的對象引用,這個時候就無法順利釋放內存。在android開發中要想避免這個問題,就要避免activity在需要回收內存的時候還在被長生命周期對象引用。

Android中長生命周期對應一般包括:

1.Application對象,不用多說了,只有在kill進程的時候生命周期才會結束。

2.內部類對象。這個問題比較隱蔽,需要注意。

3.Framework層的服務對象,比如你在activity 中listen注冊對telephony層電話監聽的時候,電話服務就持有了對你activity的引用,所以你需要在不使用的時候及時進行反注冊。

上面提到的引用基本都是強引用,在Java世界中還存在弱引用、軟引用。這兩個引用頁是解決android中內存洩露的有效武器啊,你看android框架源碼中大量使用了弱引用。

如何分析解決android系統中的內存洩露問題呢?授魚不如授漁,所以總結出一個定位問題的方法十分的重要。這裡推薦一個很好用的工具,MAT,地球人都知道吧,你只需要在eclipse中安裝這個插件就可以用了。

怎麼調試呢?先確保你的android機器可以debug,是debug版本的最好了,不然可以無法調試哦。這樣插上你的手機,打開ddms,就可以看到一串進程列表。你想調試哪個進程待會就選擇哪個。先把你的應用弄到OOM狀態,然後MAT會給你列出Suspect的內存分類,你可以看到每一塊內存當前被引用的狀態,一般情況都可以直接看出問題點。趕緊動手試試吧,如果你發現是被應用內部對象引用,那就是你的代碼寫的有問題了,檢查下是不是有被長生命周期對象在引用;如果是被framework層引用,那可能是廠商自己的BUG了。呵呵,趕緊給廠商反饋說不定還有獎勵呢。


這裡面有很多文章,一起學習下吧:

http://www.oschina.net/search?scope=blog&q=內存洩露

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved