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

所谓内存泄漏,就是本该被回收的对象,由于某些原因不能被回收,继续占用堆内存的这种状态,导致的结果也是显而易见的,会占用我们本可以使用的内存空间,当超出允许的内存时会引起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. 学习路由器vue-router

    vue-router:vue官方路由管理器. 功能:嵌套的路由/视图表模块化的.基于组件的路由配置路由参数.查询.通配符基于 Vue.js 过渡系统的视图过渡效果细粒度的导航控制带有自动激活的 CSS ...

  2. windows 2008r2+php5.6.28环境搭建详细过程

    安装IIS7 安装php 网站验证 安装IIS7 1.打开服务器管理器(开始-计算机-右键-管理-也可以打开),添加角色 直接下一步 勾选Web服务器(IIS),下一步,有个注意事项继续下一步(这里我 ...

  3. phpstudy2016+phpstorm2017-3+xdebug+chrome

    1. 勾选Xdebug 后 phpstudy 会自动重启服务 [XDebug] xdebug.profiler_output_dir="D:\phpStudy\tmp\xdebug" ...

  4. 李涛ps高手之路

    下载地址:http://www.ly89.cn/detailR/21.html

  5. selenium2-元素管理方式及解析

    1.管理文件格式:yaml 2.Yaml里面的内容格式:   3.格式说明: baidu_input后面接上":",直接回车,然后空两格 type与value这两个key是固定 ...

  6. python socket相关

    套接字的工作流程(基于TCP和 UDP两个协议) TCP和UDP对比 TCP(Transmission Control Protocol)可靠的.面向连接的协议(eg:打电话).传输效率低全双工通信( ...

  7. Mybatis中接口和对应的mapper文件位置配置详解

    Mybatis中接口和对应的mapper文件位置配置详解 原链接为:https://blog.csdn.net/fanfanzk1314/article/details/71480954 今天遇到一个 ...

  8. mysqld got signal 11

    问题发生背景 问题实例之前使用的是percona server,是安装pmm镜像自带的数据库,之后通过mysqldump迁移到了MySQL server,目前是只有有pmm server 访问pmm库 ...

  9. SpriteKit-SKView

    1.暂停这个视图 @property (nonatomic, getter = isPaused) BOOL paused; 2.视图性能的一些参数 @property (nonatomic) BOO ...

  10. Spark2.1.0之源码分析——事件总线

    阅读提示:阅读本文前,最好先阅读<Spark2.1.0之源码分析——事件总线>.<Spark2.1.0事件总线分析——ListenerBus的继承体系>及<Spark2. ...