美文网首页Android开发知识集Android_Speak
Android 内存泄漏的八种情况与防范

Android 内存泄漏的八种情况与防范

作者: sys1211 | 来源:发表于2017-04-13 18:49 被阅读17次

内存泄漏(Memory Leak)

当一个对象已经不需要使用了,本该被回收时,

而有另外一个正在使用的对象持有它的引用,从而导致了对象不能被GC回收。

内存溢出(OOM

- Out Of Memory)

当应用程序的堆(heap)资源超过了 Dalvik

虚拟机分配的内存就会内存溢出。

注:内存泄漏与内存溢出的区别与联系!

内存泄漏带来的影响:

1.

影响内存分配,造成应用程序执行效率降低;

2.

可分配的内存越少,更加容易出现内存溢出;

--------------------------------------------------------------------------------

成员变量全部存储在堆中(包括基本数据类型,引用及引用的对象实体),

因为他们属于类,类对象最终还是要被new出来的。

局部变量的基本数据类型和引用存在栈中,应用的对象实体存储在堆中。

因为它们属于方法当中的变量,生命周期会随着方法一起结束。

1.

类型

StrongReference 强引用

回收时机

任何时候GC是不能回收他的,哪怕内存不足时,

系统会直接抛出异常OutOfMemoryError,也不会去回收

生命周期

进程终止

类型

SoftReference 软引用

回收时机

当内存足够时不会回收这种引用类型的对象,只有当内存不够用时才会回收

生命周期

内存不足,进行GC的时候

2.

类型

WeakReference 弱引用

回收时机

GC一运行就会把它回收了

生命周期

GC后终止

3.

类型

PhantomReference 虚引用

回收时机

如果一个对象与虚引用关联,则跟没有引用与之关联一样,

在任何时候都可能被垃圾回收器回收

生命周期

任何时候都有可能

开发时,为了防止内存溢出,处理一些比较占用内存并且生命周期长的对象时,

可以尽量使用软引用和弱引用。

--------------------------------------------------------------------------------

1.资源未关闭造成的内存泄漏:

对于使用了

BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap

等资源的使用,

应该在Activity销毁时及时关闭或者注销,

否则这些资源将不会被回收,造成内存泄漏。

解决方案:

在Activity销毁时及时关闭或者注销。

2.单例造成的内存泄漏:

当调用getInstance时,如果传入的context 是 Activity 的 context 。

只要这个单例没有被释放,那么这个 Activity也不会被释放一直到进程退出才会释放。

解决方案:

能使用 Application 的 Context就不要使用 Activity 的 Content,

Application的生命周期伴随着整个进程的周期。

3.使用了静态的

Activity 和 View :

解决方案:

应该及时将无用的静态对象/变量置为null,

而且一般不建议将 View 及 Activity设置为静态。

4.线程造成的内存泄漏:

异步任务和 Runnable都是一个匿名内部类,

因此它们对当前 Activity都有一个隐式引用。

如果 Activity在销毁之前,任务还未完成,

那么将导致 Activity的内存资源无法回收,造成内存泄漏。

解决方案:

使用静态内部类,避免了 Activity的内存资源泄漏,

当然在 Activity销毁时候也应该取消相应的任务,

避免任务在后台执行浪费资源。

5.注册了系统的服务,但 onDestory 未注销:

解决方案:

不需要用的时候记得移除监听。

6.不需要用的监听未移除会发生内存泄露:

解决方案:

监听执行完回收对象,不用考虑内存泄漏

7.非静态内部类创建静态实例造成的内存泄漏:

解决方案:

将非静态内部类修改为静态内部类。

静态内部类不会隐式持有外部类。

8.Handler

造成的内存泄漏:

mHandler 是 Handler的非静态匿名内部类的实例,所以它持有外部类 Activity 的引用,

消息队列是在一个 Looper线程中不断轮询处理消息,

那么当这个 Activity退出时消息队列中还有未处理的消息或者正在处理消息,

而消息队列中的 Message 持有mHandler 实例的引用,

mHandler 又持有 Activity的引用,

所以导致该 Activity的内存资源无法及时回收,引发内存泄漏。

解决方案:

创建一个静态 Handler 内部类,然后对Handler 持有的对象使用弱引用,

这样在回收时也可以回收 Handler持有的对象,这样虽然避免了 Activity 泄漏,

不过 Looper线程的消息队列中还是可能会有待处理的消息,

所以在 Activity 的 onDestroy时或者 onStop 时应该移除消息队列中的消息。

相关文章

  • Android内存泄漏场景及解决方法

    本文包括以下内容: 内存泄漏原理 Android内存泄漏发生的情况 检测内存泄漏的工具、方法 如何避免内存泄漏 更...

  • Android 内存泄漏的八种情况与防范

    内存泄漏(Memory Leak) 当一个对象已经不需要使用了,本该被回收时, 而有另外一个正在使用的对象持有它的...

  • Android 内存泄漏注意点

    何为内存泄漏? 所谓内存泄漏就是无用的对象得不到释放,依然占用内存空间。 在android中都有哪些情况会出现这种...

  • android一些有用的资料

    插件化分析全面的系列文章 Android内存泄漏的情况分析

  • Android 优化

    Android 内存优化内存溢出 , 内存泄漏 , 内存泄漏过多就导致内存溢出 Android 系统垃圾回收机制内...

  • Android内存泄漏原因及解决的总结

    分三步说明Android内存泄漏的原因及解决,“内存泄漏与内存溢出的区别”,“引用方式”,“常见引发原因与解决方案...

  • (转载自diycode)2017 Android 面试题分享整理

    Android(安卓) Android基础知识 Android内存泄漏总结 Handler内存泄漏分析及解决 An...

  • android内存泄漏定位与优化

    android内存泄漏定位与优化(java篇) 内存泄漏:我们的应用内存不在GC可以掌控之内 1 垃圾回收机制(G...

  • Android 基础

    1、Android布局 2、Android内存泄漏总结 3 、Handler内存泄漏分析及解决 4...

  • android内存泄露

    参考内存泄露从入门到精通三部曲之基础知识篇Android 内存泄漏总结Android内存泄漏研究Android内存...

网友评论

    本文标题:Android 内存泄漏的八种情况与防范

    本文链接:https://www.haomeiwen.com/subject/onfiattx.html