Android内存泄漏


  • 单例模式对象造成的内存泄漏
    因为单例模式对象的静态特性使得单例的生命周期和应用的生命周期一样长,有时创建单例模式对象时需要Context对象,如果传入的是Activity的Context对象,那么当Activity生命周期结束时,该Activity的引用依然被单例模式对象持有,所以该Activity不会被回收,而单例模式对象的生命周期又是跟应用一样长,因此造成内存泄露。

  • 非静态内部类创建静态实例造成的内存泄漏
    我们如果在启动频繁的Activity中,一般会为了避免重复创建相同的数据资源,在Activity内部创建了一个非静态内部类的单例模式对象,每次启动Activity时都会使用该单例模式对象的数据,这样虽然避免了资源的重复创建。非静态内部类默认持有外部类的引用,并且使用了该非静态内部类创建了一个静态的实例,该实例的生命周期和应用的一样长,这样导致了该静态实例一直会持有该Activity的引用,导致Activity的内存资源不能正常回收。

  • Handler造成的内存泄漏
    我们在处理网络任务或者封装一些请求回调等api一般会用Handler来处理。
    首先在Activity里面这样定义一个私有的Handler对象并初始化
private Handler mHandler = new Handler(){...}

由于mHandler是Handler的非静态匿名内部类的实例,所以它持有外部类Activity的引用。当Activity产生消息时会用sendMessage()发送到消息队列(Message Queue)是在一个Looper线程中不断轮询利用dispatchMessage()发送消息给Handler的handleMessage()进行处理消息。如果这个Activity退出时消息队列中还有未处理的消息或者正在处理消息,而消息队列中的Message持有mHandler实例的引用,mHandler又持有Activity的引用,所以导致该Activity的内存资源无法及时回收,引发内存泄漏。


  • 连接或资源未关闭
    如果使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等或者HttpURLConnection,应该在Activityd销毁时在OnDestroy()函数及时关闭或者注销,否则这些资源或连接将不会被回收,造成内存泄漏。

  • 内存泄漏的排查和解决——LeakCanary
    LeakCanary是Square开源的一个内存泄露检测排查的库。使用如下:
    • 在build.gradle添加依赖
dependencies { 
        debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' 
        releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' 
        testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' 
}
  • 在Application的类中的onCreate()添加如下代码:
public class ExampleApplication extends Application {
  @Override public void onCreate() {
    super.onCreate();
    if (LeakCanary.isInAnalyzerProcess(this)) {
      // This process is dedicated to LeakCanary for heap analysis.
      // You should not init your app in this process.
      return;
    }
    LeakCanary.install(this);
    // Normal app init code...
  }
}

当在你debug应用程序时,如果应用存在内存泄漏,LeakCanary会自动显示一个通知告诉开发者哪里存在泄漏。


screenshot.png

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏大家都不陌生了,简单粗俗的讲,...
    宇宙只有巴掌大阅读 7,051评论 0 12
  • Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...
    _痞子阅读 5,565评论 0 8
  • 一.Java内存分配结构复习 1.Java内存分配策略 上一篇Android内存管理分析总结中我们提到了Java内...
    Geeks_Liu阅读 4,324评论 5 7
  • 如有论者指出,正是无数小人物以自己的生命和觉悟,书写了人类历史上最伟大的传说,而这个传说的名字就叫“自由”。只...
    云丹风卿阅读 1,639评论 0 1
  • 2017,过去了四分之一,今天又来细数,自己错过的那些风景。 今天在一位本地友人家做客。Morris像放飞的鸟儿一...
    静候师太阅读 1,585评论 0 0

友情链接更多精彩内容