Android面试题(2):一般什么情况下会导致内存泄漏问题?

这一系列文章致力于为 Android 开发者查漏补缺,面试准备。

所有文章首发于公众号「JaqenAndroid」,长期持续更新。

由于笔者水平有限,总结的答案难免会出现错误,欢迎留言指出,大家一起学习、交流、进步。

内存泄漏也是面试常见问题,主要可以考察面试者是否了解内存泄漏,工作中是如何排查解决内存泄漏问题,还可以延伸考察 Java 内存回收机制,Java 中对象的引用方式等等。

这篇文章先来介绍下 Android 开发中常见的内存泄漏案例以及相应的解决方案。

单例造成的内存泄漏

单例模式在 Android 开发中使用率非常高,但使用不恰当的话也会造成内存泄漏。比如下面的代码:

public class Singleton {

    private static Singleton sInstance;
    private Context mContext;

    private Singleton(Context context) {
        this.mContext = context;
    }

    public static Singleton getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new Singleton(context);
        }
        return sInstance;
    }
}

单例类对象的生命周期与应用的周期一样长,如果传入的是 Activity 的 Context,在 Activity 退出时,因单例对象持有 Activity 的引用,导致 Activity 的内存不能被回收,即内存泄漏。

解决方案

1)使用 Application 的 Context,生命周期一致;

2)将短生命周期的属性的引用方式改为弱引用。

非静态内部类造成的内存泄漏

非静态内部类持有外部类的引用,如果外部类的实例已经结束生命周期,但内部类仍然在执行,就会导致外部类不能被回收。比如上一期讲解的自定义 Handler 的使用造成的内存泄漏,主要原因 Activity 退出时,Handler 仍然持有 Activity 的引用,导致 Activity 不能被回收。

解决方案

1) 创建一个静态内部类,然后外部类的对象引用使用弱引用;

2)及时关闭耗时或者延时任务,在 Activity 被销毁时及时清除消息,从而及时回收 Activity,避免内存泄漏问题。

系统服务注册未取消造成的内存泄漏

系统服务可以通过 Context.getSystemService 获取,它们负责执行某些后台任务,或者为硬件访问提供接口。如果 Context 对象想要在服务内部的事件发生时被通知,那就需要把自己注册到服务的监听器中。然而,这会让服务持有 Activity 的引用,如果在 Activity 的 onDestory() 函数中没有释放掉引用就会内存泄漏。

解决方案

1)使用 Application 的 Context 代替 Activity 的 Context;

2)在 Activity 的 onDestory() 方法,调用反注册释放。

全局集合类造成的内存泄漏

一般情况下集合类不会造成内存泄漏,但如果是全局性的集合,如果在使用完毕后未进行 remove 清理操作,就很有可能造成内存泄漏,所以在集合不需要的时候要及时清理集合元素。

资源未关闭的内存泄漏

对于使用了 BroadcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap 等资源,应该在 Activity 销毁时及时关闭或者注销。

WebView 造成的内存泄漏

WebView 存在内存泄漏的问题,在应用中只要使用一次 WebView,内存就不会被释放掉。

解决方案

为 WebView 开启一个独立的进程,使用 AIDL 与应用的主进程进行通信,WebView 所在的进程可以根据业务的需要选择合适的时机进行销毁,达到正常释放内存的目的。

总结

总的来说就是生命周期长的对象持有了生命周期短的对象,导致生命周期短的对象在回收时无法被释放,就会导致内存泄漏。

了解常见内存泄漏及解决方案,能够帮助我们在开发中尽量少的出现内存泄漏问题。但有些内存泄漏的定位排查比较困难,需要借助一些工具,比如 LeakCanary、MAT 等。内存泄漏的排查定位方法会在后续文章中介绍,欢迎持续关注。

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JaqenNg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值