Android內存分析工具

Android的一些內存知識

垃圾回收(GC)

垃圾回收包含兩個過程:html

  • 斷定階段,也就是判斷哪些對象能夠被回收,android

  • 收集階段,是指具體的回收策略。git

斷定階段主要有兩種方式github

  • 引用計數,對象每多一個引用計數加1,少一個引用計數減1,計數爲0時就表示這個對象能夠被回收了。可是引用計數有個缺點,不能判斷循環應用的狀況,因此就有了下面的方式算法

  • 根搜索,從一些根對象(GCRoot)開始遍歷搜索,若是一個對象沒法被搜索到,說明這個對象能夠被回收了。 
    能夠做爲GCRoot的對象: 
    1 一些虛擬機棧中的對象;2 方法區中的類靜態屬性對象;3 方法區中的常量對象;4 Native棧中JNI的引用對象ide

收集階段主要有四種方式工具

  • 標記清除,最簡單的算法,講標記好的對象直接清除,速度快,但效率不高,內存碎片post

  • 複製算法,每次使用可用內存的一半,收集時將可用對象複製到另外一半內存,回收這一半gradle

  • 標記整理,將存活對象整理到內存區域的一端,剩餘部分回收優化

  • 分代回收,將內存區域按對象存活週期劃分爲青年代和老年代等,不一樣區域採用上面不一樣的收集算法。

Dalvik與ART

Android5.0 以前使用Dalvik虛擬機,以後使用ART虛擬機,下面是一些比較:

  • Dalvik在運行時將字節碼轉換爲機器碼,ART在安裝的時候就轉換爲機器碼,這樣安裝好的應用會佔用更大的空間,可是運行時少了轉換的時間,因此運行更快

  • ART提供了更好的垃圾回收表現,將垃圾回收時,程序的暫停次數由兩次(分析、清理)減小到一次;程序暫停時,並行的進行垃圾回收處理;回收新近分配的、生命期短的對象,垃圾回收器花費的時間更少

Android內存分析工具

Memory Monitor

GC操做須要暫停其餘線程,所以短期頻繁的GC會對UI線程產生影響,致使頻繁GC通常有兩種狀況,

  • 大量的對象被建立又在短期內立刻被釋放,好比在View的onDraw方法中建立對象

  • Young Generation的內存區域達到閥值,剩餘空間不夠的時候,也會觸發頻繁GC

Android Studio提供了Memory Monitor來實時顯示應用運行時內存佔用狀況,下邊藍色部分是如今佔用的內存,上面灰色的部分顯示是已回收的內存。若是在圖上看到尖峯,也就是快速分配內存又被回收,也就是發生了內存抖動,這裏就是須要優化的地方。

Allocation Tracking

Allocation Tracking是DDMS中提供內存工具,用來顯示一段時間內的內存分配狀況。

選擇要跟蹤的進程名,點擊Start Tracking開始跟蹤,作一些操做後點擊Get Allocations就能夠將這段操做中新分配的對象顯示出來,點擊具體的對象能夠在下面看到是哪個方法分配的這個對象。

Heap Tool 與 MAT

Heap Tool能夠查看當前的內存快照

從數據裏能夠看到當前內存的佔用和回收狀況,每次垃圾回收這裏的數據都會更新,由於會不斷獲取內存數據刷新顯示,因此這時候對應用操做會出現卡頓。 
Heap Tool提供的是一個內存的整體狀況,圖表顯示的內容比較簡單,若是要具體分析的話最好生成.hprof文件,使用MAT工具進行分析。

關於MAT工具的使用已經有不少介紹,google官方曾經寫過一個使用介紹http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html,推薦一箇中文博客, 
http://blog.csdn.net/guolin_blog/article/details/42238633,寫的很好。

通常用到MAT工具分析內存都是由於發生了應用發生了內存泄漏,須要本身去分析可能泄漏的地方,而後用MAT工具去驗證。而最近Square公司開源了一個內存泄漏檢測項目LeakCanary,極大地簡化了這個過程,能夠說是Android內存泄漏檢測的終極利器。

LeakCanary

A memory leak detection library for Android and Java. 
項目地址:https://github.com/square/leakcanary

LeakCanary

LeakCanary會檢測應用的內存回收狀況,若是發現有垃圾對象沒有被回收,就會去分析當前的內存快照,也就是上邊MAT用到的.hprof文件,找到對象的引用鏈,並顯示在頁面上。

使用: 
在build.gradle文件中添加

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

在應用的Application onCreate方法中添加LeakCanary.install(this),以下

public class ExampleApplication extends Application {

  @Override public void onCreate() {    super.onCreate();
    LeakCanary.install(this);
  }
}1234567

應用運行起來後,LeakCanary會自動去分析當前的內存狀態,若是檢測到泄漏會發送到通知欄,點擊通知欄就能夠跳轉到具體的泄漏分析頁面。

Tips:就目前使用的結果來看,絕大部分泄漏是因爲使用單例模式hold住了Activity的引用,好比傳入了context或者將Activity做爲listener設置了進去,因此在使用單例模式的時候要特別注意,還有在Activity生命週期結束的時候將一些自定義監聽器的Activity引用置空。

關於LeakCanary的更多分析能夠看項目主頁的介紹,還有這裏http://www.liaohuqiu.net/cn/posts/leak-canary-read-me/

Reference

http://sr1.me/way-to-explore/2014/06/20/what-is-art-to-android.html 
http://www.infoq.com/cn/news/2014/07/art-runtime 
http://android.jobbole.com/80926/ 
http://www.liaohuqiu.net/cn/posts/leak-canary-read-me/

相關文章
相關標籤/搜索