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/

相关文章
相关标签/搜索