1. 程式人生 > >使用 Android Studio 檢測記憶體洩漏與解決記憶體洩漏問題

使用 Android Studio 檢測記憶體洩漏與解決記憶體洩漏問題

  本文在騰訊技術推文上 修改 釋出。  

  http://wetest.qq.com/lab/view/63.html?from=ads_test2_qqtips&sessionUserType=BFT.PARAMS.195040.TASKID&ADUIN=913337456&ADSESSION=1468996652&ADTAG=CLIENT.QQ.5431_.0&ADPUBNO=26510

自從Google在2013年釋出了Android Studio後,Android Studio憑藉著自己良好的記憶體優化,酷炫的UI主題,強大的自動補全提示以及Gradle的編譯支援正逐步取代Eclipse,成為主流的Android開發IDE。Android Studio在為我們提供了良好的編碼體驗的同時,也提供了許多對App效能分析的工具,讓開發者可以更方便分析App效能。Google在IO大會上一直告誡開發者不要無節制的使用手機記憶體,要注意一些不良的開發習慣會導致App的記憶體洩漏。雖然如今網上檢測App記憶體洩漏的文章汗牛充棟,但是要使用DDMS和MAT,不僅使用步驟複雜繁瑣,而且要手動排查記憶體洩漏的位置,操作起來多有不便。其實Android Studio已經開始支援自動進行記憶體洩漏檢查了,本文就帶著大家一探其中的奧妙吧。


什麼是記憶體洩漏
  這個也是個面試常客,通俗來說,定義了的變數沒使用,就是記憶體洩漏了。Android虛擬機器的垃圾回收採用的是根搜尋演算法,還一種是程式計數器演算法。GC會從根節點(GC Roots)開始對heap進行遍歷。到最後,部分沒有直接或者間接引用到GC Roots的就是需要回收的垃圾,會被GC回收掉。而記憶體洩漏出現的原因就是存在了無效的引用,導致本來需要被GC的物件沒有被回收掉。


舉個例子

mLeak是儲存在靜態區的靜態變數,而Leak是內部類,其持有外部類Activity的引用。這樣就導致Activity需要被銷燬時,由於被mLeak所持有,所以系統不會對其進行GC,這樣就造成了記憶體洩漏。


再舉一個最常犯的例子

  如果我們在在呼叫Singleton的getInstance()方法時傳入了Activity。那麼當instance沒有釋放時,這個Activity會一直存在。因此造成記憶體洩露。
解決方法可以將new Singleton(context)改為new Singleton(context.getApplicationContext())即可,這樣便和傳入的Activity沒關係了。


記憶體洩漏的檢測
  開啟Android Studio,編譯程式碼,在模擬器或者真機上執行App,然後點選,在Android Monitor下點選Monitor對應的Tab,進入如下介面

  在Memory一欄中,可以觀察不同時間App記憶體的動態使用情況,點選可以手動觸發GC,點選可以進入HPROF Viewer介面,檢視Java的Heap,如下圖

  Reference Tree代表指向該例項的引用,可以從這裡面檢視記憶體洩漏的原因,Shallow Size指的是該物件本身佔用記憶體的大小,Retained Size代表該物件被釋放後,垃圾回收器能回收的記憶體總和。
下面我們以掌上道聚城客戶端為例,來一探記憶體洩漏檢測的方法。
  開啟Android Studio,編譯程式碼,執行掌上道聚城,然後開始盡情的耍我們的App啦,然後就從Memory Monitor裡面觀察App的記憶體使用曲線,突然發現,納尼!!!怎麼記憶體使用越來越大了,這就很有可能是發生記憶體洩漏了,然後點選手動進行GC,再點選觀看JavaHeap,點選Analyzer Task,Android Monitor就可以為我們自動分析洩漏的Activity啦,分析出來如下圖所示

  在Reference Tree裡面,我們直接就可以看到持有該Activity的單例物件,直接定位到該單例中的程式碼,發現程式碼中出現了

   

  和剛剛舉得例子裡出現的錯誤一模一樣,我們修復了檢查出的記憶體洩漏的問題,並將修復前和修復後的程式碼在相同的模擬器上執行並進行相同的操作,檢視他們使用記憶體的情況,如下圖所示

有記憶體洩漏的情況,佔用記憶體約為43M

   修復了記憶體洩漏問題,佔用記憶體為36M在修復了記憶體洩漏問題後,記憶體使用下降了16.3%!!! 最後補充一個我遇到的例子 優化程式碼後,明顯解決了上述問題 最後,在掌握了Android Monitor的使用方法後,相信能在android開發的路上助各位一臂之力。

相關推薦

使用 Android Studio 檢測記憶體洩漏解決記憶體洩漏問題

  本文在騰訊技術推文上 修改 釋出。     http://wetest.qq.com/lab/view/63.html?from=ads_test2_qqtips&sessionUserType=BFT.PARAMS.195040.TASKID&ADUIN=913337456&a

使用Android studio 的Analyzer Task分析解決activity記憶體洩漏問題

最近接手的一個老專案,功能比較繁雜,是執行在安卓pos機上面的收銀系統,基本需要應用整天在前臺使用,對系統穩定性要求較高,不同於一般app。 今天做了記憶體方面的檢測 首先我們用電腦連線裝置,用cmd執行adb的記憶體檢測的命令 adb shell dumpsys mem

使用Android Studio檢測記憶體洩露

記憶體洩露,是Android開發者最頭疼的事。可能一處小小的記憶體洩露,都可能是毀千里之堤的蟻穴。 怎麼才能檢測記憶體洩露呢? AndroidStudio 中Memory控制元件臺(顯示器)提供了一個記憶體監視器。我們可以通過它方便地檢視應用程式的效能和記憶體

使用新版Android Studio檢測記憶體洩露和效能

記憶體洩露,是Android開發者最頭疼的事。可能一處小小的記憶體洩露,都可能是毀於千里之堤的蟻穴。 怎麼才能檢測記憶體洩露呢?網上教程非常多,不過很多都是使用Eclipse檢測的, 其實1.3版本以後的Android Studio 檢測記憶體非常方便, 如果結合上MAT工具,LeakCanary外掛,一

Android studio檢視應用的日誌和記憶體

1、安裝Android studio後開啟,執行下系統預設的程式 2、開啟除錯模式,Tools–Android–Enable ADB Integration–勾選 3、檢視日誌 點選底部And

常見Java記憶體溢位解決方法詳解

Java programming language具有目前大部分程式語言所共有的一些特徵,被特意設計用於網際網路的分散式環境。Java具有類似於C++語言的"形式和感覺",但它要比C++語言更易於使用,而且在程式設計時徹底採用了一種"以物件為導向"的方式。使用Java編寫的

使用新版Android Studio檢測內存泄露和性能

qq空間 fun selection book 檢測 內存 lips info ava http://www.jianshu.com/p/216b03c22bb8 內存泄露,是Android開發者最頭疼的事。可能一處小小的內存泄露,都可能是毀於千裏之堤的蟻穴。怎麽

android studio更新gradle失敗的解決辦法-轉

簡書 wrapper all mina wrap 技術 有一個 class tar android studio中每次自動更新gradle時速度實在太慢因為gradle服務器比較慢,所以更新gradle會比較慢,建議先下載下來,然後手動添加到gradle的下載目

安卓第一課:android studio 的環境搭建真機運行以及遇到的問題

自己的 安卓 structure 最好 not found 創建過程 cor 虛擬 col AS的下載: https://developer.android.com/studio/index.html AS的安裝: android studio, sdk, virtual

Android Studio更改工程名異常解決方案 :can't rename root module

包括 extern ext 相關 文件名 post roo 手動 修改文件 在修改Android Studio 中 project的名字時 ,提示 “can’t rename root module”。 這是因為Android S

android studio bug : aidl is missing 解決方案

visio ogr example tin .html using 項目 tac users 很久不打開Android studio 今天打開一下,發現之前配置好的開發環境不能用了! 項目中“R.”變紅了,運行結果如下,可以說很怪,電腦沒動過,怎麽回事呢? 於是Stack

Android Studio匯入gradle專案問題解決

        放棄了eclipse轉投Android Studio,發現原來的import project 都變得麻煩了許多,記錄一下匯入一個專案遇到的各種坑, 可能以後還會遇到,也可以為他人作個參考。  &n

物理機記憶體模型java記憶體模型

多執行緒快取一致性問題 程式在執行過程中,會將運算需要的資料從主存複製一份到CPU的快取記憶體當中,那麼CPU進行計算時就可以直接從它的快取記憶體讀取資料和向其中寫入資料,當運算結束之後,再將快取記憶體中的資料重新整理到主存當中。 在單執行緒的情況下,這沒有任何問題,但在多核CPU中(多執行緒),每條執行

Android Studio 自動文字提示下拉列表

1.自動文字提示 1.1.佈局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/and

Android Studio 下載、安裝配置(開發環境搭建)

下載jdk8並安裝. 下載並安裝AndroidStudio。因為anroid.com無法訪問,可以從https://developer.android.google.cn/studio/獲取。 安裝AndroidStudio後,會自動下載Android SDK及其他

android studio執行卡慢的解決方案

androidstudio安裝目錄下 bin/studio64.exe.vmoptions 檔案:配置檔案 將引數調大,比如。 -Xms2048m -Xmx2048m -XX:MaxPermSize=2048m -XX:ReservedCodeCacheSiz

Android Studio:Metadata失敗,Download失敗解決

這兩個錯誤原因多半是因為你的網路不能訪問外網. 下面我們通過設定代理解決; 我們使用的是Shadowsocks: 要確保你的伺服器可用可訪問外網; 現在轉到Android Studio設定代理: Setting->搜尋 proxy: 127.0.0.1表示用本機做代理,也

Ubuntu下Android Studio 出現 “processDebugResources” 錯誤的解決

之前一直很順暢,自從裝了SubVersion後出現如下錯誤: Error:Execution failed for task ':app:processDebugResources'. > com.android.ide.common.process.Proce 解決

Java記憶體區域Java記憶體模型

原子性:原子性指的是一個操作是不可中斷的,即使是在多執行緒環境下,一個操作一旦開始就不會被其他執行緒影響。比如對於一個靜態變數int x,兩條執行緒同時對他賦值,執行緒A賦值為1,而執行緒B賦值為2,不管執行緒如何執行,最終x的值要麼是1,要麼是2,執行緒A和執行緒B間的操作是沒有干擾的,這就是原子性操作,不

Android studio 打包string報錯解決方法

在build.gradle(Module:app)中新增 android {  lintOptions {         checkReleaseBuilds false         // Or, if you prefer, you can continue t