App常見內存泄漏以及解決方法

如果是想認真學習的話,請先不要看以下內容,此記錄只是爲加深記憶,可能會有錯誤的地方,以免有誤導。

學習轉載鏈接:https://blog.csdn.net/u014674558/article/details/62234008

App常見內存泄漏以及解決方法

1、非靜態內部類,靜態實例化

/**
 * 自定義實現的Activity
 */
public class MyActivity extends AppCompatActivity {
    /**
     * 靜態成員變量
     */
    public static InnerClass innerClass = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        innerClass = new InnerClass();
    }

    class InnerClass {

        public void doSomeThing() {
        }
    }
}

內部類InnerClass隱式持有外部類MyActivity的引用,在MyActivity的onCreate方法中調用innerClass = new  InnerClass();

innerClass會在MyActivity創建的時候就有了它的引用,而innerclass是靜態類型,不會被垃圾回收,MyActivity在執行onDestory方法的時候由於被innerClass持有引用而無法被回收,所以這樣MyActivity就總是被innerClass持有而無法回收造成內存泄漏

 

2、不正確的使用Context對象,造成內存泄漏

比如在Android幫助類中,會有很多引用Context

/**
 * 自定義單例對象
 */
public class Single {
    private static Single instance;
    private Context context;
    private Object obj = new Object();

    private Single(Context context) {
        this.context = context;
    }

    /**
     * 初始化獲取單例對象
     */
    public static Single getInstance(Context context) {
        if (instance == null) {
            synchronized(obj) {
                if (instance == null) {
                    instance = new Single(context);
                }
            }
        }
        return instance;
    }
}

解決方法:使用全局的Context或者context.getApplication();

3、使用handler異步消息通信

日常開發中我們通常這樣定義Handler對象:

/**
 * 定義Handler成員變量
 */
Handler handler = new Handler() {  
        @Override  
        public void handleMessage(Message msg) {  
            dosomething();  

        }  
    };

這樣存在一個隱藏問題:在Activity中使用Handler創建的匿名內部類會隱式持有外部Activity對象,當子線程使用Handler暫時無法完成異步任務時,handler對象無法銷燬,同時隱式持有的activity以及相關的組件與資源文件同樣無法銷燬,在成內存泄漏。我們普通的handler,平時使用時也是可以不用考慮這些,但是在子線程中有耗時操作通知UI時,要考慮這一點

解決方法:

使用靜態變量定義handler,靜態變量無法操作activity中的對象,所以需要在handler對象中添加一個對activity的弱引用

static MyHandler handler = new MyHandler (this) {  

        @Override  
        public void handleMessage(Message msg) {  
            dosomething();  

        }  
    };  

static class MyHandler extends Handler {  
    WeakReference<Activity > mActivityReference;  
    MyHandler(Activity activity) {  
        mActivityReference= new WeakReference<Activity>(activity);  
    }  
    @Override  
    public void handleMessage(Message msg) {  
        final Activity activity = mActivityReference.get();  
        if (activity != null) {  
            mImageView.setImageBitmap(mBitmap);  
        }  
    }  
} 

最後在onDestory方法中將後面的消息移除  handler.removeCallbackAndMessages(null);

4、使用了屬性屬性動畫或循環動畫

在Activity中使用了屬性循環動畫,在onDestory()方法中未正確停止動畫

5、使用資源文件結束之後未關閉

在使用一些資源性對象(比如Cusor,File,Stream,ContentProvider等)往往都用了一些緩衝,我們在不使用的時候,應該及時關閉它們,以便它們的緩衝及時回收內存,它們的緩衝不僅存在於java虛擬機中,還存在與java虛擬機外。如果我們僅僅是把它們設置爲null,而不去close關閉,仍然會造成內存泄漏

6、Bitmap使用不當

bitmap對象使用的內存比較大,當我們不再使用bitmap對象的時候一定要執行recycle方法,執行該方法不會立即釋放掉,只是通知虛擬機該bitmap可以被recycle了

7、一些框架使用了註冊方法而未反註冊

比如我們常用的時間總線框架-EventBus,當我們需要註冊某個Activity時,需要在onCreate中:

EventBus.getDefault().register(this);

則EventBus對象持有該Activity的引用,及時onDestory,仍然無法回收,需要在onDestory方法中調用

EventBus.getDefault().unregister(this);

8、集合中的一些方法的錯誤使用

比如list列表靜態化,只是添加元素而不再使用時不清除元素;

map對象只是put,沒有remove操作等;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章