---
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. Codeigniter使用phpexcel

    1. 去 http://phpexcel.codeplex.com/ 下载phpexcel源码,解压缩后把phpexcel/Classes里的PHPExcel文件夹和PHPExcel.php复制到CI ...

  2. JavaEE Tutorials (14) - 用实体图创建获取计划

    14.1实体图基础185 14.1.1默认实体图186 14.1.2在持久化操作中使用实体图18614.2使用命名实体图187 14.2.1对实体类应用命名实体图注解187 14.2.2从命名实体图获 ...

  3. HDU 5877 Weak Pair(树状数组)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5877 [题目大意] 给出一棵带权有根树,询问有几对存在祖先关系的点对满足权值相乘小于等于k. [题 ...

  4. CodeForces 235C Cyclical Quest(后缀自动机)

    [题目链接] http://codeforces.com/contest/235/problem/C [题目大意] 给出一个字符串,给出一些子串,问每个子串分别在母串中圆环匹配的次数,圆环匹配的意思是 ...

  5. ural 1057(数位dp)

    数位dp题,关键是用树的思维去考虑. 对于一个数字X,要是能表示成K个B的不同次幂,等价于X在B进制下有且只有K个位上面的数字为一,其他位上的数字都为0. 具体读者可以去参考,国家集训队李聪的论文,里 ...

  6. poj 1815 Friendship (最小割+拆点+枚举)

    题意: 就在一个给定的无向图中至少应该去掉几个顶点才干使得s和t不联通. 算法: 假设s和t直接相连输出no answer. 把每一个点拆成两个点v和v'',这两个点之间连一条权值为1的边(残余容量) ...

  7. SSIS Package 配置多数据库连接语句

  8. 纯css加伪类实现关闭提示创窗口

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8&quo ...

  9. Objective-c 数组对象

    首先我们必须知道数组的概念:数组是有序的对象集合,一般情况下,一个数组的对象都是相同类型的.数组当中也存在可变数组和不可变数组. 1. 不可变数组 (NSArray) 可变数组 NSMutable 是 ...

  10. JavaScript使用button提交表单

    <form action="test.html" method="POST"> <input type="button" ...