• Android开发中容易造成内存泄露的原因汇总
  • 卡卡 发表于 2016/3/3 12:57:00 | 分类标签: Android开发 性能优化 内存泄露
  • 最近进行技术支持的时候,遇到了几个崩溃的问题,都是OOM异常,一般OOM异常给人的感觉应该是加载大图片造成的,但是经过看界面布局,并且分析加载图片的大小发现加载图片方面已经没有什么可以优化的了,但是依然崩溃,没办法了,又用的IDEA工具中的内存监视器,来判断到底是哪里造成内存激增,做哪些操作造成页面资源没有及时释放。最后发现原来是每次关闭这个界面,都没有及时的释放资源,每次开启,都会重新申请资源,造成内存泄露问题。下面我就说一下我们写代码的时候,那些地方容易会造成内存泄露

    首先是在Activity中声明静态变量或者静态方法或者静态控件

    静态变量或者方法是放在静态数据区的,也就是在程序运行的过程中,只要加载过这个类之后,静态的变量或者方法,就一直会在静态数据区存在,不会释放资源。因为静态变量或者方法不是凭空存在的,所以需要Activity作为支撑,也就是说这个变量不仅占用了变量本身所存放数据的内存,还占据了这个Activity所占的内存。也就是这个Activity即使被用户关闭了,但是资源并没有被释放。

    其次,一些读取数据库动态注册广播没有及时关闭注销也是容易造成内存泄露的

    例如例如BroadcastReceiver、ContentObserver,FileObserver在Activity的onDeatory或者某类的生命周期结束后,一定要unregister掉,否则这个Activity会一直被system强引用,不会被内存回收。

    单例模式导致的内存泄露

    单例模式的特点就是他的生命周期和Application一样,如果某个Activity示例被一个单利所持有,也就是说单利里面引用了他,就会造成Activity对象会无法正常回收释放。

    注:这里的原理和第一种是一样的,都是因为静态变量引用Activity对象,造成Activity无法正常释放资源造成的。

     
    属性动画导致内存泄露

    例如代码中设置了属性动画(ObjectAnimator),在Activity中启动了动画,但是在销毁的时候,没有调用cancle方法,虽然我们看不到动画了,但是这个动画依然会不断地播放下去,动画引用所在的控件,所在的控件引用Activity,这就造成Activity无法正常释放。

    Handler内部类造成内存泄露

    当使用内部类(包括匿名内部类)来创建Handler的时候,Handler对象会隐式的持有一个外部类对象(通常是Activity)的引用,而handler通常会伴随这一个耗时的后台线程(例如从网络拉取图片)一起出现,这个后台线程在任务执行完毕之后,通过消息机制,通知Handler然后Handler见图片更新到界面,如果用户在网络请求中关闭了Activity,正常情况下,Activity不再被使用,因该会被Gc回收掉,但是,由于该线程未执行完,而该线程持有的Handler的引用,就导致Activity无法被回收(直到网络请求结束),如果你执行了Handler的postDelayed()方法,该方法会将你的Handler装入一个Message,并把这条Message推到MessageQueue中,那么在你设定的delay到达之前,会有一条MessageQueue -> Message -> Handler -> Activity的链,导致你的Activity被持有引用而无法被回收。可以在Activity结束后,关闭线程,如果你的Handler是被delay的Message持有了引用,那么调用void removeCallbacksAndMessages(null)方法来移除消息队列。
  • 请您注意

    ·自觉遵守:爱国、守法、自律、真实、文明的原则

    ·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规

    ·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品

    ·承担一切因您的行为而直接或间接导致的民事或刑事法律责任

    ·您在编程中国社区新闻评论发表的作品,本网站有权在网站内保留、转载、引用或者删除

    ·参与本评论即表明您已经阅读并接受上述条款

  • 感谢本文作者
  • 作者头像
  • 昵称:卡卡
  • 加入时间:2013/5/17 0:00:00
  • TA的签名
  • 这家伙很懒,虾米都没写
  • +进入TA的空间
  • 以下内容也很赞哦
分享按钮