内存泄漏问题老生常谈,很常见也很难根治,今天我在这里总结一下内存泄漏的原因和解决方法:

所谓内存泄漏,就是本该被回收的对象,由于某些原因不能被回收,继续占用堆内存的这种状态,导致的结果也是显而易见的,会占用我们本可以使用的内存空间,当超出允许的内存时会引起OOM崩溃。

导致内存泄漏的原因大致分为:

  1. 集合类
  2. static修饰的成员变量
  3. 资源对象使用后未被关闭
  4. 非静态内部类/匿名类

1.集合类引起的内存泄漏:

当一个对象添加至集合中的时候,该对象会被集合引用到,当想要释放的时候不能释放,只有在集合被销毁的时候该对象才可以被释放

 // 通过 循环申请Object 对象 & 将申请的对象逐个放入到集合List
List<Object> objectList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Object o = new Object();
objectList.add(o);
o = null;
}
// 虽释放了集合元素引用的本身:o=null)
// 但集合List 仍然引用该对象,故垃圾回收器GC 依然不可回收该对象

解决方法:

因为是集合把对象引用了,那只需要吧集合释放掉集合对元素的引用也会被释放

//释放集合
objectList .clear();
objectList = null;

2.static修饰的成员变量:

因为被static修饰的成员变量生命周期 = 应用程序的生命周期,会在类被创建的时候加载到内存

static静态成员变量的生命周期>该类的生命周期导致该类没法释放

public class SecondActivity extends Activity{
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
SecondActivity.this.finish();
this.removeMessages(0);
}
}; private static Haha haha;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
haha = new Haha();
mHandler.sendEmptyMessageDelayed(0,2000);
} class Haha{ }
}

像上面这种情况SecondActivity是无法被释放掉的,只有把该静态成员变量置为null,这时就不会导致内存泄漏

protected void onDestroy() {
super.onDestroy();
if(haha!=null){
haha = null;
}
}

更常见的问题是在我们使用单例模式的时候:

public class LeakSingleInstance {

    private static LeakSingleInstance mInstance;
private Context mContext; private LeakSingleInstance(Context mContext){
this.mContext = mContext;
}
public static LeakSingleInstance getInstance(Context mContext) {
if(mInstance == null) {
mInstance = new LeakSingleInstance(mContext);
}
return mInstance;
}
}

这个在创建的时候AndroidStudio就提示有内存泄漏了,原因显而易见的,我们的单例模式的类是长期存在的,生命周期 = 应用生命周期,我们如果传入了上下文会导致该上下文长期被持有,不被释放,导致内存泄漏

解决方法可以使用:

mContext.getApplicationContext()

直接获取ApplicationContext的上下文使用,但是ApplicationContext使用是有局限性的,使用的时候要注意。

3.资源对象使用后未被关闭

对于资源的使用(如 广播BraodcastReceiver、文件流File、数据库游标Cursor、图片资源Bitmap等),若在Activity销毁时无及时关闭 / 注销这些资源,则这些资源将不会被回收,从而造成内存泄漏

// 对于 广播BraodcastReceiver:注销注册
unregisterReceiver() // 对于 文件流File:关闭流
InputStream / OutputStream.close() // 对于 数据库游标cursor:使用后关闭游标
cursor.close() // 对于 图片资源Bitmap:Android分配给图片的内存只有8M,若1个Bitmap对象占内存较多,当它不再被使用时,应调用recycle()回收此对象的像素所占用的内存;最后再赋为null
Bitmap.recycle();
Bitmap = null; // 对于动画(属性动画)
// 将动画设置成无限循环播放repeatCount = “infinite”后
// 在Activity退出时记得停止动画

还有非静态内部类和匿名类引起的泄漏,留在下篇再分析

by:Jungle张轶

Android内存泄漏总结的更多相关文章

  1. 【转】android 内存泄漏相关收藏博客。

    关于android内存泄漏的研究   博客建了几个月,都没有去写,一是因为当时换工作,然后又是新入职(你懂的,好好表现),比较忙:二是也因为自己没有写博客的习惯了.现在还算是比较稳定了,加上这个迭代基 ...

  2. 关于android内存泄漏的研究

    博客建了几个月,都没有去写,一是因为当时换工作,然后又是新入职(你懂的,好好表现),比较忙:二是也因为自己没有写博客的习惯了.现在还算是比较稳定了,加上这个迭代基本也快结束了,有点时间来写写博客.好了 ...

  3. Android内存泄漏的各种原因详解

    转自:http://mobile.51cto.com/abased-406286.htm 1.资源对象没关闭造成的内存泄漏 描述: 资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我 ...

  4. Android 内存泄漏优化汇总

    android内存泄漏优化摘要 博客分类: android android内存溢出OutOfMemoryError . android移动应用程序的内存分配一般是8凯瑟琳约,不正确地假定处理内存处理非 ...

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

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

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

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

  7. [Android]Android内存泄漏你所要知道的一切(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/7235616.html Android内存泄漏你所要知道的一切 ...

  8. LeakCanary 来检查 Android 内存泄漏

    LeakCanary 来检查 Android 内存泄漏

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

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

  10. Android内存泄漏原因

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

随机推荐

  1. python入门:py2.x里面除法或乘法这么写就可以计算小数点后面结果

    #!/usr/bin/env python # -*- coding:utf-8 -*- #py2.x里面除法或乘法这么写就可以计算小数点后面结果,更精确future(未来,译音:非忧车) divis ...

  2. 15.Yii2.0框架where单表查询

    目录 新建控制器 HomeController.php 新建model article.php 新建控制器 HomeController.php D:\xampp\htdocs\yii\control ...

  3. 拼接Python字符串最常见的六种方式

    最常见的六种方式拼接Python字符串 字符串是所有编程语言中都有的基本变量的类型,程序员基本每天都在和字符串打交道. 每种字符串拼接方式的使用场景各不相同,我们可以在开发过程中灵活运用. 一.用逗号 ...

  4. hdu 5459

    Problem Description I've sent Fang Fang around 201314 text messages in almost 5 years. Why can't she ...

  5. list_for_each_entry()函数分析

    list_for_each原型: #define list_for_each(pos, head) \ for (pos = (head)->next, prefetch(pos->nex ...

  6. POJ2239二分匹配

    开始以为是最长路,想着把每一门课程的每一节课时作为一个点去建有向图...然后写的时候发现点太多了(300*7*12)建图特麻烦,就果断放弃了这个思路. 然后开始用排除法来想用什么算法合适,没环不可能缩 ...

  7. Leetcode 464.我能赢吗

    我能赢吗 在 "100 game" 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和达到 100 的玩家,即为胜者. 如果我们将游戏规则改为 ...

  8. Django创建并连接数据库(实现增删改查)--第二版

    注意点一: url里面的地址,不只是html页面,准确说是views视图里面对应的函数方法 <!DOCTYPE html> <html lang="en"> ...

  9. rsync配置和同步数据

    rsync的搭建配置1.环境和配置文件 rsyncd.conf(主配置文件) rsyncd.secrets(密码文件) pc1:192.168.0.1,rsync的服务器,配置rsyncd.conf文 ...

  10. 设计模式(一)单例模式:3-静态内部类模式(Holder)

    思想: 相比于懒汉以及饿汉模式,静态内部类模式(一般也被称为 Holder)是许多人推荐的一种单例的实现方式,因为相比懒汉模式,它用更少的代码量达到了延迟加载的目的. 顾名思义,这种模式使用了一个私有 ...