1. 程式人生 > >Android 記憶體洩露和效能檢測

Android 記憶體洩露和效能檢測

Android Studio的記憶體分析介面

一般分析記憶體洩露, 首先執行程式,開啟日誌控制檯,有一個標籤Memory ,我們可以在這個介面分析當前程式使用的記憶體情況, 一目瞭然, 我們再也不需要苦苦的在logcat中尋找記憶體的日誌了。

圖中藍色區域,就是程式使用的記憶體, 灰色區域就是空閒記憶體

當然,Android記憶體分配機制是對每個應用程式逐步增加, 比如你程式當前使用30M記憶體, 系統可能會給你分配40M, 當前就有10M空閒, 如果程式使用了50M了,系統會緊接著給當前程式增加一部分,比如達到了80M, 當前你的空閒記憶體就是30M了。 當然,系統如果不能再給你分配額外的記憶體,程式自然就會OOM(記憶體溢位)了。 每個應用程式最高可以申請的記憶體和手機密切相關,比如我當前使用的華為Mate7,極限大概是200M,算比較高的了, 一般128M 就是極限了, 甚至有的手機只有可憐的16M或者32M,這樣的手機相對於記憶體溢位的概率非常大了。

我們怎麼檢測記憶體洩露呢

首先需要明白一個概念, 記憶體洩露就是指,本應該回收的記憶體,還駐留在記憶體中。一般情況下,高密度的手機,一個頁面大概就會消耗20M記憶體,如果發現退出介面,程式記憶體遲遲不降低的話,可能就發生了嚴重的記憶體洩露。我們可以反覆進入該介面,然後點選dump java heap 這個按鈕,然後Android Studio就開始幹活了,下面的圖就是正在dump

正在dump

dump成功後會自動開啟 hprof檔案,檔案以Snapshot+時間來命名

記憶體分析結果

通過Android Studio自帶的介面,檢視記憶體洩露還不是很智慧,我們可以藉助第三方工具,常見的工具就是MAT了,下載地址

http://eclipse.org/mat/downloads.php ,這裡我們需要下載獨立版的MAT. 下圖是MAT一開始開啟的介面, 這裡需要提醒大家的是,MAT並不會準確地告訴我們哪裡發生了記憶體洩漏,而是會提供一大堆的資料和線索,我們需要自己去分析這些資料來去判斷到底是不是真的發生了記憶體洩漏。

LeakCanary

上面介紹了MAT檢測記憶體洩露, 再給大家介紹LeakCanary。 專案地址:https://github.com/square/leakcanaryLeakCanary 會檢測應用的記憶體回收情況,如果發現有垃圾物件沒有被回收,就會去分析當前的記憶體快照,也就是上邊MAT用到的.hprof檔案,找到物件的引用鏈,並顯示在頁面上。這款外掛的好處就是,可以在手機端直接檢視記憶體洩露的地方,可以輔助我們檢測記憶體洩露.

手機端檢視記憶體洩露.png

使用: 在build.gradle檔案中新增,不同的編譯使用不同的引用:

dependencies {  
      debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3' 
      releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
 }

在應用的Application onCreate方法中新增LeakCanary.install(this),如下:

public class ExampleApplication extends Application  
  @Override  
  public void onCreate() { 
      super.onCreate();  
      LeakCanary.install(this);
   } 
}

應用執行起來後,LeakCanary會自動去分析當前的記憶體狀態,如果檢測到洩漏會發送到通知欄,點選通知欄就可以跳轉到具體的洩漏分析頁面。Tips:就目前使用的結果來看,絕大部分洩漏是由於使用單例模式hold住了Activity的引用,比如傳入了context或者將Activity作為listener設定了進去,所以在使用單例模式的時候要特別注意,還有在Activity生命週期結束的時候將一些自定義監聽器的Activity引用置空。

作者:於連林520wcf連結:https://www.jianshu.com/p/216b03c22bb8來源:簡書著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

是什麼?

一言以蔽之:LeakCanary是一個傻瓜化並且視覺化的記憶體洩露分析工具

為什麼需要LeakCanary?

因為它簡單,易於發現問題,人人可參與。

  • 簡單:只需設定一段程式碼即可,開啟應用執行一下就能夠發現記憶體洩露。而MAT分析需要Heap Dump,獲取檔案,手動分析等多個步驟。
  • 易於發現問題:在手機端即可檢視問題即引用關係,而MAT則需要你分析,找到Path To GC Roots等關係。
  • 人人可參與:開發人員,測試測試,產品經理基本上只要會用App就有可能發現問題。而傳統的MAT方式,只有部分開發者才有精力和能力實施。

如何整合

儘量在app下的build.gradle中加入以下依賴

1
2
3
4
5
 dependencies {
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' // or 1.4-beta1
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta1
   testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta1
 }

在Application中加入類似如下的程式碼

1
2
3
4
5
6
7
public class ExampleApplication extends Application {
  @Override public void onCreate() {
    super.onCreate();
    LeakCanary.install(this);
  }
}

到這裡你就可以檢測到Activity的內容洩露了。其實現原理是設定Application的ActivityLifecycleCallbacks方法監控所有Activity的生命週期回撥。內部實現程式碼為

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public final class ActivityRefWatcher {
    private final ActivityLifecycleCallbacks lifecycleCallbacks = new ActivityLifecycleCallbacks() {
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        }
        public void onActivityStarted(Activity activity) {
        }
        public void onActivityResumed(Activity activity) {
        }
        public void onActivityPaused(Activity activity) {
        }
        public void onActivityStopped(Activity activity) {
        }
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        }
        public void onActivityDestroyed(Activity activity) {
            ActivityRefWatcher.this.onActivityDestroyed(activity);
        }
    };
    private final Application application;
    private final RefWatcher refWatcher;
    public static void installOnIcsPlus(Application application, RefWatcher refWatcher) {
        if(VERSION.SDK_INT >= 14) {
            ActivityRefWatcher activityRefWatcher 
            
           

相關推薦

Android 記憶體洩露效能檢測

Android Studio的記憶體分析介面 一般分析記憶體洩露, 首先執行程式,開啟日誌控制檯,有一個標籤Memory ,我們可以在這個介面分析當前程式使用的記憶體情況, 一目瞭然, 我們再也不需要苦苦的在logcat中尋找記憶體的日誌了。圖中藍色區域,就是程式使用的

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

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

android必備記錄筆記(一)記憶體洩露各種效能優化

該篇筆記來自於平時學習時,對各種學習資源的整合,如有冒犯敬請諒解,整理的不好,還望海涵指出錯誤 一、記憶體洩露 針對記憶體洩露我認為要知道下面三點: 第一:要弄清楚記憶體洩露與記憶體溢位的區別 第二:要弄清楚常規的記憶體分析方法,重點掌握Leakcanary的使用和原

android記錄筆記(一)記憶體洩露各種效能優化

該篇筆記來自於平時學習時,對各種學習資源的整合,如有冒犯敬請諒解,整理的不好,還望指出錯誤,主要用於查詢與記錄 一、記憶體洩露 針對記憶體洩露我認為要知道下面三點: 第一:要弄清楚記憶體洩露與記憶體溢位的區別 第二:要弄清楚常規的記憶體分析方法,重點掌握Leakcanary的使用

Android記憶體洩露檢測工具實際開發中遇到的記憶體洩露問題解析

介紹 記憶體洩露是平常開發中經常遇到的,有些時候稍不注意就會發生,而且還不易察覺,這就需要工具來幫助檢測。本文主要介紹記憶體檢測工具和我在開發中遇到的記憶體洩露問題和解決方案。 記憶體洩露的原理 具體的原理涉及到虛擬機器垃圾回收機制知識,這裡只為下文作

使用命令列檢測Android記憶體洩露

首先我們用電腦連線裝置,用cmd執行adb的記憶體檢測的命令 adb shell dumpsys meminfo com.screening 後面的com.screening是包名,要改成自己的 執行後顯示的資訊 這裡面需要關心的有:HeapSi

效能優化篇---記憶體管理之Android記憶體洩露

記憶體洩漏:當你不再需要某個例項後,但是這個物件卻仍然被引用,防止被垃圾回收。這個情況就叫做記憶體洩露(Memory Leak)。 常見洩漏場景: 1.Handler 導致的記憶體洩漏 12345678910111213141516171819202122 publ

Android面試準備:記憶體洩露記憶體溢位

概念 記憶體洩露:申請的記憶體沒有及時釋放掉,這樣的話就會造成程式能使用的記憶體資源越來越少,最終會導致系統無法再提供記憶體資源; 譬如說,一個map裡面一直在新增新的物件,這樣的話就很有可能造成記憶體洩露。 記憶體溢位:就是要求分配的記憶體超出了系統提供

Android記憶體洩露案例解析

使用過長物件生命週期 靜態引用 靜態變數儲存在方法區,在類載入的時候被載入,除非類被解除安裝了,或者他會一直存活,直到App程序銷燬,也就是說靜態變數的生命期等於整個程序的生命期。 private Context mContext;

Android產品研發(二十四)-->記憶體洩露場景與檢測

上一篇文章中本文我們講解了一個Android產品研發中可能會碰到的一個問題:如何在App中儲存靜態祕鑰以及保證其安全性。許多的移動app需要在app端儲存一些靜態字串常量,其可能是靜態祕鑰、第三方appId等。在儲存這些字串常量的時候就涉及到了如何保證祕鑰的

Android記憶體洩露分析

一,記憶體洩露 記憶體洩露:一個不在被使用的物件被另一個存活著的物件引用,在這種情況下垃圾回收器會跳過他,因為這種引用關係足以讓該物件駐留在記憶體中,記憶體洩露是在組織垃圾回收器為未來的記憶體分配提供空間,這些洩露的物件一直佔據著記憶體,導致我們的堆記憶體空間變得更小。也加劇了垃圾回

記憶體洩露記憶體溢位的區別 (概念區別 產生原因區別 及解決辦法) 個人整理

記憶體洩露和記憶體溢位的區別 概念區別 記憶體溢位 : out of memory 指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out fo memory 比如申請一個integer 但給它存了long才能存下的數那就是記憶體溢位 記憶體洩露 : memory leak 指程

轉載:Android 記憶體洩露分析實戰演練

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://mp.csdn.net/postedit/82736058 轉載自任玉剛微信推文,非常全面所以記錄下來 1. 記憶體洩露簡介 記憶體洩露,即Memory Leak,指程式中不再使用到的物件因某種原因從而無法被GC正常回

JavaScript 的記憶體洩露垃圾回收

什麼是記憶體洩露 ? 任何程式語言,在執行時都需要使用到記憶體,比如在一個函式中, var arr = [1, 2, 3, 4, 5]; 這麼一個數組,就需要記憶體。 但是,在使用了這些記憶體之後, 如果後面他們不會再被用到,但是還沒有及時釋放,這就叫做記憶體洩露(memory

記憶體洩露 記憶體溢位

記憶體溢位 out of memory,是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory; 記憶體洩漏(Memory Leak)是指程式中己動態分配的堆記憶體由於某種原因程式未釋放或無法釋放,造成系統記憶體的浪費,導致程式執行速度減慢甚至系統崩潰等嚴重後果。

記憶體洩露javaScript的記憶體管理機制

1.記憶體洩漏(Memory Leak) 是指程式中己動態分配的堆記憶體由於某種原因程式未釋放或無法釋放,造成系統記憶體的浪費,導致程式執行速度減慢甚至系統崩潰等嚴重後果 2.javaScri

android記憶體洩露深入研究

首先抄上百科 隱式記憶體洩漏:程式在執行過程中不停的分配記憶體,但是直到結束的時候才釋放記憶體。嚴格的說這裡並沒有發生記憶體洩漏,因為最終程式釋放了所有申請的記憶體。但是對於一個伺服器程式,需要執行幾天,幾周甚至幾個月,不及時釋放記憶體也可能導致最終耗盡系統的所有記憶體。所

Android記憶體洩露利器(hprof篇)

set processName=com.sec.android.app.dialertab;android.process.acore;com.sec.android.provider.logsprovider

Qt中記憶體洩露半自動記憶體管理

Qt中幫程式設計師做了一些記憶體回收的事情,但正因為這些反而讓對此不熟悉的人會屢屢犯錯。 收錄一篇不錯的文章: 在C++中學習過程中,我們都知道: delete 和 new 必須 配對使用(一 一對應):delete少了,則記憶體洩露,多了麻煩更大。 Qt作為C++的庫

OpenCL入門:(三:GPU記憶體結構效能優化)

#include <iostream> #include <CL/cl.h> #include <cassert> #include <windows.h> #include <ctime> using namespace std; #defin