Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android編程入門 >> Android性能優化——之防止內存洩露

Android性能優化——之防止內存洩露

編輯:Android編程入門

又是好久沒有寫博客了,一直都比較忙,最近終於有時間沉澱和整理一下最近學到和解決的一些問題。

最近進行技術支持的時候,遇到了幾個崩潰的問題,都是OOM異常,一般OOM異常給人的感覺應該是加載大圖片造成的,但是經過看界面布局,並且分析加載圖片的大小發現加載圖片方面已經沒有什麼可以優化的了,但是依然崩潰,沒辦法了,又用的IDEA工具中的內存監視器,來判斷到底是哪裡造成內存激增,做哪些操作造成頁面資源沒有及時釋放。最後發現原來是每次關閉這個界面,都沒有及時的釋放資源,每次開啟,都會重新申請資源,造成內存洩露問題。下面我就說一下我們寫代碼的時候,那些地方容易會造成內存洩露。

首先是在Activity中聲明靜態變量或者靜態方法或者靜態控件

靜態變量或者方法是放在靜態數據區的,也就是在程序運行的過程中,只要加載過這個類之後,靜態的變量或者方法,就一直會在靜態數據區存在,不會釋放資源。因為靜態變量或者方法不是憑空存在的,所以需要Activity作為支撐,也就是說這個變量不僅占用了變量本身所存放數據的內存,還占據了這個Activity所占的內存。也就是這個Activity即使被用戶關閉了,但是資源並沒有被釋放。

其次,一些讀取數據庫動態注冊廣播沒有及時關閉注銷也是容易造成內存洩露的

例如例如BroadcastReceiver、ContentObserver,FileObserver在Activity的onDeatory或者某類的生命周期結束後,一定要unregister掉,否則這個Activity會一直被system強引用,不會被內存回收。

單例模式導致的內存洩露,

單例模式的特點就是他的生命周期和Application一樣,如果某個Activity示例被一個單利所持有,也就是說單利裡面引用了他,就會造成Activity對象會無法正常回收釋放。

注:這裡的原理和第一種是一樣的,都是因為靜態變量引用Activity對象,造成Activity無法正常釋放資源造成的。

 

屬性動畫導致內存洩露

例如代碼中設置了屬性動畫(ObjectAnimator),在Activity中啟動了動畫,但是在銷毀的時候,沒有調用cancle方法,雖然我們看不到動畫了,但是這個動畫依然會不斷地播放下去,動畫引用所在的控件,所在的控件引用Activity,這就造成Activity無法正常釋放。

 

Handler內部類造成內存洩露

當使用內部類(包括匿名內部類)來創建Handler的時候,Handler對象會隱式的持有一個外部類對象(通常是Activity)的引用,而handler通常會伴隨這一個耗時的後台線程(例如從網絡拉取圖片)一起出現,這個後台線程在任務執行完畢之後,通過消息機制,通知Handler然後Handler見圖片更新到界面,如果用戶在網絡請求中關閉了Activity,正常情況下,Activity不再被使用,因該會被Gc回收掉,但是,由於該線程未執行完,而該線程持有的Handler的引用,就導致Activity無法被回收(直到網絡請求結束),如果你執行了Handler的postDelayed()方法,該方法會將你的Handler裝入一個Message,並把這條Message推到MessageQueue中,那麼在你設定的delay到達之前,會有一條MessageQueue -> Message -> Handler -> Activity的鏈,導致你的Activity被持有引用而無法被回收。可以在Activity結束後,關閉線程,如果你的Handler是被delay的Message持有了引用,那麼調用void removeCallbacksAndMessages(null)方法來移除消息隊列。

 

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