使用单例模式时,有时候不小心,就会很容易造成内容泄漏,如下代码所示:

public class SingleInstance
{
private static volatile SingleInstance instance;
private Context context;
private SingleInstance(Context context)
{this.context = context;
}
public static SingleInstance getInstance(Context context)
{if(instance == null){synchronized(SingleInstance.class){if(instance == null){instance = new SingleInstance(context);}}}return instance;}
}
public class MainActivity extends Activity
{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//leak occuredSingleInstance.getInstance(this);}
}

上面的代码中,传入给单例对象的context是Activity的context,而单例对象是一个static对象,其生命周期与应用程序是一致的,(也就是说,只有应用程序进程被杀掉了,static对象才会被销毁,因为static是类对象,而不是对象变量),该SingleInstance单例静态对象持有当前Activity的context,当MainActivity退出时,由于instance还继续只有其context引用,对造成系统无法销毁该Activity,从而造成内存泄漏。

解决方法:

从以上分析中,可以看成,造成内存泄漏的主要原因就是static对象的生命周期与其持有对象引用(即Activity)的声明周期不同而造成的,因此,解决内存的泄漏的方法有如下2种:

  1. 使用应用程序的getApplicationContext(),静态对象的生命周期与应用程序的生命周期一致,故此不会导致内存泄漏。

  2. 持有传入的context的弱引用。如下所示:

private WeakReference<Context> weakContext;
private SingleInstance(Context context)
{weakContext = new WeakReference<Context>(context);
}

如果某个时间点,MainActivity被GC了,由于持有的是MainActivity的弱引用,不会影响系统对MainActivity的回收,那么context就被置空了,所以后面要使用该context时,就需要判断一下该若引用持有的对象是否还存在:

weakContext.get() != null

转载于:https://blog.51cto.com/whatever957/1834138

由单例模式造成的内存泄漏相关推荐

  1. 单例模式引发的内存泄漏:_资源泄漏:救援的命令模式

    单例模式引发的内存泄漏: 多年来, 使用Plumbr进行性能监控时,我遇到了数百个资源泄漏引起的性能问题. 在这篇文章中,我想描述一种最简单的方法来清理资源并避免该问题. 首先,我以电影播放器​​应用 ...

  2. java 单例 内存释放_周小抒 – 梦想仗剑走天涯 | Android中关于Context单例模式引起的内存泄漏以及解决方案...

    内存溢出与内存泄漏的区别: 内存溢出是由于应用所消耗的内存或者应用申请的内存超出了虚拟机分配的内存,也就是内存不够用了. 内存泄漏是某个不再使用对象由于被其他实例引用,导致不能被GC回收,而导致的内存 ...

  3. Android性能优化——内存泄漏优化

    内存泄漏的优化分为两个方面 一方面:开发过程中避免写出有内存泄漏的代码 . 另一方面:通过一些分析工具比如MAT来找出潜在的内存泄露从而解决 场景1:静态变量导致的内存泄漏 场景2:单例模式导致的内存 ...

  4. java内存泄漏总结

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

  5. Android 内存泄漏总结文档

    2019独角兽企业重金招聘Python工程师标准>>> Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题.内存泄漏大家都不陌生 ...

  6. android编译非静态内部类,Android 非静态内部类/匿名类引起的内存泄漏

    一.概述 让我们先来回顾一下android内存泄漏的相关概念: 内存溢出:android系统会给每个安卓程序分配一定的内存,当程序所使用的内存超过最大值就会造成内存溢出,就是常说的OOM 内存泄漏:简 ...

  7. Java中关于内存泄漏分析和解决方案,都在这里了!

    作者:李序锴 www.jianshu.com/p/54b5da7c6816 最近正在熟悉Java内存泄漏的相关知识,上网查阅了一些资料,在此做个整理算是对收获的一些总结,希望能对各位有所帮助,有问题可 ...

  8. 来点干货 | Android 常见内存泄漏与优化(二)

    作者 | 无名之辈FTER 责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 在昨天的Android 内存泄漏问题多多,怎么优化?一文中,我们详细阐述了Java虚拟机工作原理和Androi ...

  9. Android 内存泄漏问题多多,怎么优化?

    作者 | 无名之辈FTER 来源 | CSDN博客 责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 众所周知,Java因其拥有独特的虚拟机(JVM)设计,使其成为一门跨平台.内存自动管理 ...

最新文章

  1. UML系列图--用例图
  2. Windows PE 第十章 加载配置信息
  3. map和struct的多重嵌套
  4. php补充 扩展,php补充安装扩展支持
  5. lg gw880 qq2011 android beta4版,LG GW880评测:CMMB天线、细节设计
  6. php图像处理原生函数,php图像处理函数imagecopyresampled的用法
  7. 物以类聚:对象也有生命
  8. linux上启动git,linux上git操作与打jar包更新启动服务脚本
  9. C#:抽象类和抽象函数, 密封类和密封方法(抄录自LilianChen)
  10. 查看计算机本机IP地址,本机ip地址查询
  11. gooflow学习笔记
  12. 经典sql练习题(oracle版)
  13. 分享116个PHP源码PHP源码,总有一款适合你
  14. ArcGIS网络分析扩展模块
  15. jquery boxy插件
  16. js前端实现单个或多个直播视频播放方法总结hls,rtsp
  17. 数控机床是什么编程php吗,数控车床编程实例
  18. ActiveMQ学习(二)——MQ的工作原理
  19. 【详细】三种主流跨平台技术探讨
  20. 用ssh方法scp,从本地传输文件到服务器

热门文章

  1. Ubuntu下安装Pycharm及相关设置
  2. bzoj4403:序列统计
  3. day 012 生成器 与 列表推导式
  4. left join on and 与 left join on where的区别
  5. tensorflow的一些函数
  6. 用Ant编译Flex项目的几点注意事项
  7. SilverLight非托管代码的初始化进度条方法
  8. d3.js 实现烟花鲜果
  9. 错误MSB4018 “ResolvePackageAssets”任务意外失败的解决方法
  10. 使用 TypeScript 改造构建工具及测试用例