转载请标明出处:https://www.cnblogs.com/tangZH/p/10955429.html

                           http://77blogs.com/?p=230

泄漏,泄漏,漏~

内存泄漏怎么破,什么是内存泄漏?与内存溢出有什么区别?

内存泄漏(Memory Leak):是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

内存溢出(out of memory):是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;

内存泄漏不一定会引起奔溃,但是内存溢出一定会

Java里头有GC垃圾回收机制,他是怎么判断该不该回收呢?

Q1:某对象没有任何引用的时候才进行回收?

A:不。无法往上追溯到GCroot引用点的才回收。

Q2:某对象被别的对象引用就不能进行回收?

A:不。软引用,弱引用,虚引用都可以


哪些可以作为GCroot引用点:

  • Javastack中引用的对象
  • 方法区中静态引用指向的对象
  • 方法区中常量引用指向的对象
  • Native方法中JNI引用指向的对象
  • Thread-活着的线程

adb命令验证是否存在内存泄漏:

1、打开要测试的apk,然后返回退出到主界面

2、AS的Terminal中输入命令:

     adb shell dumpsys meminfo com.status.mattest -d 

com.status.mattest为包名

然后便可以看到内存的一些情况

拉到下面可以看到:

我们退出APK之后,对象本应该都被回收,然而这里可以看到,还有view以及Activity占用着内存,由此可以知道内存泄漏了。


我们点击AS上的按钮,进行分析。

运行apk后会出现该界面:

我们点击MEMORY进入内存分析界面:

这时候我们需要进行刚刚的操作,打开apk,然后返回键退出,然后点击上图中垃圾桶形状的图标进行垃圾回收,多点几次,直到内存没有什么变化了。

然后点击上图中类似于下载按钮的图标获取内存快照。

获取完之后,左边会出现下面这图,Head Dump便是获取内存快照后出现的,我们可以点击红圈中的图形进行保存

跟着出现的还有这个窗口。

我们可以通过包来分类查看自己的项目.

Shallow Heap(浅堆) 表示该对象自身占用的堆内存,不包括它引用的对象。
针对非数组类型的对象,它的大小就是对象与它所有的成员变量大小的总和。

Retained Heap(深堆) 表示当前对象大小+当前对象可直接或间接引用到的对象的大小总和。
换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。

不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage。

从图中可以看出,出现了内存泄漏的是CustomUtils,MainActivity,MainActivity$1代表MaiActivity里面的一个方法。

点击MainActivity,可以看到这么对东西,眼花缭乱,我们根本不知道是哪个引起了内存泄漏。那咋办。铺垫结束,mat该上场了。

MAT

下载mat https://www.eclipse.org/mat/downloads.php

安装步骤很简单。

打开MAT后,点击File -> Open Heap Dump 打开刚刚保存的内存快照,会发现打不开。

因为我们保存的内存快照是不能直接在MAT上打开的,需要进行转化。

在AS的Terminal窗口输入:hprof-conv -z A.hprof B.hprof

A.hprof为刚刚保存后的快照文件,B.hprof为转换后的文件,也就是我们要在MAT上打开的文件

然后我们在MAT上将其打开。

点击Finish

点击Histogram

 可以通过包名来分类查看

从下图中可以看到引起内存泄漏的类,Objects那一列不为0的就是,与我们之前看到的一样。

MainActivity右键

选择图中的选项,意思是过滤掉虚引用,软引用,弱引用

之后可以看到引用的路径,CustomUtils里面的instance引用了MainActivity的context,导致了MainActivity内存泄漏。

打开代码看一下

package com.status.mattest;

import android.content.Context;

public class CustomUtils {
private static CustomUtils instance; private CustomUtils(Context context) {
this.mContext = context;
} private Context mContext; public static CustomUtils getInstance(Context context) {
if (instance == null) {
instance = new CustomUtils(context);
} return instance;
}
}

MainActivity中:

package com.status.mattest;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView; public class MainActivity extends AppCompatActivity { private TextView textView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CustomUtils customUtils = CustomUtils.getInstance(this);
textView = findViewById(R.id.tv);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, Test1Activity.class));
}
});
}
}

MainActivity中调用了单例CustomUtils,并且把context传了进去,而我们知道instance作为静态对象,是GCroot引用点,所以activity关闭了它也没法被回收,那么最为被instance引用的Activity自然也无法被回收,所以导致了内存泄漏。

解决:

把单例模式里面的context换为全局application的context,也就是说单例里面的context的周期应该与进程一样,而不能够与应用一样。当我们关闭应用的时候,进程还在,并没有被杀死。

MAT分析android内存泄漏的更多相关文章

  1. Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  2. Android内存泄漏的检测流程、捕捉以及分析

    https://blog.csdn.net/qq_20280683/article/details/77964208 Android内存泄漏的检测流程.捕捉以及分析 简述: 一个APP的性能,重度关乎 ...

  3. Android 内存泄漏总结

    内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题.内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却不再被使用导致 GC 不能回收 ...

  4. Android内存泄漏检测利器:LeakCanary

    Android内存泄漏检测利器:LeakCanary MAR 28TH, 2016 是什么? 一言以蔽之:LeakCanary是一个傻瓜化并且可视化的内存泄露分析工具 为什么需要LeakCanary? ...

  5. Android内存泄漏原因

    这段时间调试APP的时候,发现程序在加载了过多的bitmap后会崩溃.查看了日志,原来是发生了内存溢出(OOM).第一次遇到这样的问题,那就慢慢排查吧. 内存优化可以参考胡凯大神的博客Android内 ...

  6. Android 内存泄漏总结(转)

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题.内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却 ...

  7. Android - 内存泄漏 + 垃圾回收(GC)概念

    Android内存泄露——全解析和处理办法 内存泄露 说到内存泄露,就不得不提到内存溢出,这两个比较容易混淆的概念,我们来分析一下. 内存泄露:程序在向系统申请分配内存空间后(new),在使用完毕后未 ...

  8. 使用MAT分析Java内存

    Overview MAT(Memory Analyzer Tool) 是一个JAVA Heaper分析器,可以用来分析内存泄露和减少内存消耗.分析Process showmap中的/dev/ashme ...

  9. 简单通俗讲解 android 内存泄漏

    在柠檬班社区看到老师一篇android 内存泄漏写的通俗易懂,绝对是小白能看懂的! 原文:http://www.lemfix.com/topics/2 平常会听到程序员说"内存泄漏" ...

随机推荐

  1. Golang中的布隆过滤器

    目录 1. 布隆过滤器的概念 2. 布隆过滤器应用场景 3. 布隆过滤器工作原理 4. 布隆过滤器的优缺点 5. 布隆过滤器注意事项 6. Go实现布隆过滤器 1. 布隆过滤器的概念 布隆过滤器(Bl ...

  2. luogu P3984 高兴的津津

    题目描述 津津上高中了.她在自己的妈妈的魔鬼训练下,成为了一个神犇,每次参加一次OI比赛必拿Au虐全场.每次她拿到一个Au后就很高兴.假设津津不会因为其它事高兴,并且她的高兴会持续T天(包包含获奖当天 ...

  3. [TimLinux] JavaScript 获取元素节点的5种方法

    1. getElementById document.getElementById("id_value") # 返回值为Node对象,没有元素时,返回 == undefined值( ...

  4. ARTS-S docker ceontos镜像中使用crontab

    centos镜像中默认没有crontab,需要在dockerflle中通过yum的安装 yum -y install vixie-cron crontabs && yum clean ...

  5. centos与内核版本对应关系

    centos是基于redhat的二次开发,redhat会封装不同版本的内核,有时候,我们需要指定内核版本的centos,下面两个网站或许对你有帮助: https://access.redhat.com ...

  6. 基于python的种子搜索网站(三)项目部署

    项目部署过程 系统要求:ubuntu 16.04(或以上) 环境搭建和配置,必须严格按照以下步骤来安装部署!如有问题可以咨询(weixin:java2048) 安装部分 安装nginx sudo ap ...

  7. Flume理论研究与实验

    一.理论研究 1.1 总览 Flume是一个分布式的可靠的日志收集系统,主要是用于从各种数据源收集.聚合并移动大批量的日志数据到存储系统:它本身具有许多故障转移和恢复机制,具有强大的容错能力:它使用下 ...

  8. 《一头扎进》系列之Python+Selenium框架设计篇3- 价值好几K的框架,狼来了,狼来了....,狼没来,框架真的来了

    1. 简介 前边宏哥一边一边的喊框架,就如同一边一边的喊狼来了!狼来了!.....这回是狼没有来,框架真的来了.从本文开始宏哥将会一步一步介绍,如何从无到有地创建自己的第一个自动化测试框架.这一篇,我 ...

  9. 使用where 过滤数据

    --本章主要内容是MySQL中使用where搜索条件进行过滤数据. where条件在from子句后面给出,如下所示: select name,price from shops where price& ...

  10. android 7.0+、8.0+应用中点击拍照崩溃的解决办法

    在开发中,项目里面明明已经添加过拍照或者读取相册的权限,但是在点击拍照或者打开相册的时候应用会崩溃,报一下错误: Caused by: android.os.FileUriExposedExcepti ...