---
layout: post
title: 工具篇-MAT(Memory Analyzer Tool)
description: 让内存泄漏无所遁形 2015-10-08
category: blog
---

## 让内存泄漏无所遁形##

----------

### 一、android 垃圾回收机制的理解 ###
**1、堆和栈** - 至少我们需要知道,我们写的一句代码,它的所需要的内存是放到哪里的。
至于如何释放堆和栈这些细节,此次略过一万字,请大家自行google.
    
堆heap:内存数据区;简单来说,保存了对象的实例:对象的属性值;对象从堆申请完内存之后会生成一个地址存在stack里边。heap的释放是有jvm回收器来负责的。

栈stack:内存指令区;简单来说,保存了对象的实例里边的属性类型,方法地址,基本类型,如int,float,常量,静态变量都是存在栈里边的。栈里边内存的释放是FILO(first in ,last out)会自动释放。

简单来说,new 创建的一个对象,大部分内存都是放在heap里的。

native 内存 和 ashmem 是不属于jvm gc范围的;

**2、拉贾回收器**

垃圾收集算法的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。

触发条件:

- 手动调用System.gc(),只是建议触发GC,并不保证每次都能GC
 - app空闲时,gc的线程优先级是极低的,此时可能会调用GC
 - heap内存申请不足时,会强制触发gc,若GC一次还不够,则会进行第二次GC,若内存还不够,则会引发OOM;
**GC引发的直观问题,频繁的GC会导致app的用户体验:UI卡顿,耗电;**

由GC想起的一些编码细节:

(1)能用int就不要用Integer
        (2)大对象不用时最好设置为null
        (3)尽量避免产出大量的临时对象
        (4)使用StringBuffer代替String拼接字符串,String拼接会产生多个垃圾对象
        (5)尽量少使用静态变量,静态变量属于全局变量,不会被GC回收,它们会一直占用内存。
        (6)activity切记不要被全局单例类引用。

----------

###二、MAT-Memory Analyzer tool ###
此工具可以帮我们分析出当前使用的app存留在内存里对象有哪些,并能跟踪到具体的引用对象,从而找出内存泄漏的原因。

1、MAT下载地址:[点击进入](http://www.eclipse.org/mat/downloads.php)

2、了解几个参数的含义:

DDMS参数:
        a、Heap Size 系统为此进程所分配堆的大小,当资源增加,
          当前堆的空余空间不够时,系统会增加堆的大小,
          若超过上限 (例如64M,视平台和具体机型而定)则会被杀掉
        b、Allocated 堆中已分配的大小,这是应用程序实际占用的内存大小,资源回收后,此项数据会变小

MAT工具参数:
        Histogram:列出当前存留对象和数量
        Dominator Tree:由大到小列举出对象以及他们含有什么。
        Path to GC Root:显示GC路径的path
        
![此处输入图片的描述](http://7xnby9.com1.z0.glb.clouddn.com/actions.jpg)

###二、MAT-Memory Analyzer tool 使用步骤 ###

1、dump内存文件:

使用DDMS的dump工具dump出你所选中进程的文件;

步骤:
    1、选择进程,点击update heap;
    2、再手机上打开你想要检测的页面
    3、狂戳GC直到Allocated的值不再下降为止;
    4、再点击一下update heap带有红色向下箭头的按钮,稍等片刻,会自动弹出文件保存框;
    5、保存dump文件到本地;
![此处输入图片的描述](http://7xnby9.com1.z0.glb.clouddn.com/dump.jpg)
![此处输入图片的描述](http://7xnby9.com1.z0.glb.clouddn.com/heap.jpg)

注意:
    1、eclipse自带的mat插件可自动转换dump文件格式,可直接用mat工具打开;
    2、IDEA或者android studio dump的出的hprof文件是需要转换的
      转换命令是:hprof-conv src.hprof dest.hprof,完了之后再用mat工具打开;
打开dump文件后如下图:
![此处输入图片的描述](http://7xnby9.com1.z0.glb.clouddn.com/over_view.jpg)

2、Dominator Tree如下图:
![此处输入图片的描述](http://7xnby9.com1.z0.glb.clouddn.com/dominator_tree.jpg)
点击之后如图,此时右键图选中行-》List Objects->with outgoing refrences找到外部应用的对象,如下图:
![此处输入图片的描述](http://7xnby9.com1.z0.glb.clouddn.com/outgoing_two.jpg)
此处找到了Bitmap的引用对象,然后右键-》GC ROOT PATHS-》exclude weak/soft....排除软弱引用找到强引的对象,如下图:
![此处输入图片的描述](http://7xnby9.com1.z0.glb.clouddn.com/topic_mengban.jpg)
到这里就能知道是哪里的业务代码导致了内存泄漏,从图中可看出
mBitmap来源于ImageView
ImageView来源-ll_mengban的child
ll_mengban来源-TopicDetailActivity的控件
TopicDetailActivity context被 mmsdk引用了;
从而导致mBitmap无法释放;
然后我们来看看TopicDetailActivity是如何被强引用的:
在TopicDetailActivity的onCreate里执行了
        
        shareController = new ShareController(this);
然而ShareController执行了这个:
        
        public ShareController(Activity activity) {
            mActivity = activity;
            ShareLoginController.getInstance(mActivity).addLoginListener(this);
        }
然而ShareLoginController执行了这个:

public ShareController(Activity activity) {
            mActivity = activity;
            ShareLoginController.getInstance(mActivity).addLoginListener(this);
        }

然而ShareLoginController构造方法执行了这个:

public ShareLoginController(Activity activity) {
            if (mController == null) {
                try {
                    mController =(UMSocialService) BeanManager.getSocialService(activity);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(loginListeners==null){
                loginListeners = new ArrayList<IShareLoginListener>();
            }
        }

然而UMSocialService里把context传递给了QQsdk,导致了一直被强引用无法GC的原因;

找到了问题,解决办法就是去除这个强引用即可;

-----------------------
博客:http://iceAnson.github.io

http://iceanson.github.io/tool-mat/

工具篇-MAT(Memory Analyzer Tool)的更多相关文章

  1. 使用MAT(Memory Analyzer Tool)工具分析dump文件--转

    原文地址:http://gao-xianglong.iteye.com/blog/2173140?utm_source=tuicool&utm_medium=referral 前言 生产环境中 ...

  2. MAT(Memory Analyzer Tool)工具入门介绍

    1.MAT是什么? MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速.功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 ...

  3. MAT(Memory Analyzer Tool)工具入门介绍(转)

    1.MAT是什么? MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速.功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 ...

  4. 【转】MAT(Memory Analyzer Tool)工具入门介绍

    1.MAT是什么? MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速.功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 ...

  5. 内存分析工具-MAT(Memory Analyzer Tool)

    内存分析工具-MAT(Memory Analyzer Tool) 首先查看如下代码,main函数中有一个成员变量map,map里被循环放入对象Hanson,hanson持有姓名和age还有friend ...

  6. MAT Memory Analyzer Tool 插件安装(图解)

    MAT Memory Analyzer Tool 插件安装(图解) 原文地址 @author YHC 前段时间做了一个项目,Exception in thread "main" j ...

  7. Android 内存分析工具 MAT(Memory Analyzer Tool)

    如果使用DDMS确实发现了我们的程序中存在内存泄漏,那又如何定位到具体出现问题的代码片段,最终找到问题所在呢?如果从头到尾的分析代码逻辑,那肯定 会把人逼疯,特别是在维护别人写的代码的时候.这里介绍一 ...

  8. MAT(Memory Analyzer Tool)内存分析工具的使用

    开发.应用中老是会遇到OutOfMemory异常,而且常常是过一段时间内存才被吃光,这里可以利用java heap dump出jvm内存镜像,然后再对其进行分析来查找问题. 平常利用jmap -dum ...

  9. 转载:MAT Memory Analyzer Tool使用示例

    地址:http://blog.csdn.net/yanghongchang_/article/details/7711911 以下是一个会导致java.lang.OutOfMemoryError: J ...

  10. [性能测试]:内存泄漏以及MAT(Memory Analyzer Tool)工具使用分析

    一.今天在查看服务器时候,发现内存使用率直接就到99%了, 二.用ps -uaxw查看一下,每个占用内存较多的进程情况: 三,挑出可疑的进程,生成dump文件: jmap -dump:format=b ...

随机推荐

  1. JS中的this都有什么作用?

    1.全局代码中的this  是指向全局对象,在浏览器中是window alert(this) //window 2.作为单纯的函数调用: function fooCoder(x) { this.x = ...

  2. python自学笔记(一)简单了解python

    脚本解释型语言的内部机制 python先将脚本编译成字节码文件(pyc,pyo) python虚拟机解释并运行字节码文件 编译型语言的内部机制 先将源代码编译成机器码(机器能读懂的代码),生成可执行文 ...

  3. 查看ORACLE 数据库及表信息

    -- 查看ORACLE 数据库中本用户下的所有表 SELECT table_name FROM user_tables; -- 查看ORACLE 数据库中所有用户下的所有表 select user,t ...

  4. 转: mysql create view 创建视图

    以下的文章主要是对MySQL视图的描述,其中包括MySQ视图L概述,以及创建MySQL视图-create view与修改MySQL视图--alter view等相关内容的具体描述,以下就是文章的具体内 ...

  5. VS2012生成绿色版程序的方法

    方法就是在工程属性里设置: 配置属性-〉常规-〉项目默认值-〉MFC的使用-〉在静态库中使用MFC,见下图 之后重新编译即可.

  6. c# winform读取xml创建菜单

    动态创建菜单使得程序灵活性大大增加,本文根据读取xml文件中的配置菜单项来动态创建菜单,代码如下: using System; using System.Collections.Generic; us ...

  7. 学习pthreads,给线程传递多个參数

    上篇博文中.boss线程给其它线程传递的仅仅有一个參数,那么假如是多个參数呢?怎么传递呢?也许你会有这种疑问,带着这个疑问,我们进入本文的世界,这里传递多个參数,採用结构体,为什么呢?由于结构体里能够 ...

  8. java String.Format详解

    JDK1.5中,String类新增了一个很有用的静态方法String.format(): format(Locale l, String format, Object... args) 使用指定的语言 ...

  9. zoj 1083 Frame Stacking

    其实就是一个拓补排序.(动态记录第i个之上的j存不存在,反过来就是第j个之下的i) 首先确立每个框的位置(题目明确说了每一边都不会被完全覆盖)./*可以通过搜索,搜索到该框的所有四个角*/||如果题目 ...

  10. ##DAY6 UIScrollView

    ##DAY6 UIScrollView #pragma mark ———————UIScrollView——————————— 属性: contentSize 内容滚动范围 contentOffset ...