Android内存泄漏定位、分析、解决全方案

本文详细探讨了Android内存泄漏的原因,包括Context、Bitmap、集合、注册、资源对象等问题,并提供了相应的解决策略,如避免静态Activity、及时释放Bitmap、取消注册、关闭资源等。此外,还介绍了检测内存泄漏的方法,如Lint、LeakCanary和Android Monitor,以及四种引用类型的介绍。
摘要由CSDN通过智能技术生成

为什么会发生内存泄漏


内存空间使用完毕之后未回收, 会导致内存泄漏。有人会问:Java不是有垃圾自动回收机制么?不幸的是,在Java中仍存在很多容易导致内存泄漏的逻辑(logical leak)。虽然垃圾回收器会帮我们干掉大部分无用的内存空间,但是对于还保持着引用,但逻辑上已经不会再用到的对象,垃圾回收器不会回收它们。

例如

  • 忘记释放分配的内存的。(Cursor忘记关闭等)。
  • 应用不再需要这个对象,未释放该对象的所有引用。
  • 强引用持有的对象,垃圾回收器是无法在内存中回收这个对象。
  • 持有对象生命周期过长,导致无法回收。

Java判断无效对象的原理

Android内存回收管理策略图:

 

图中的每个圆节点代表对象的内存资源,箭头代表可达路径。当圆节点与 GC Roots 存在可达路径时,表示当前资源正被引用,虚拟机是无法对其进行回收的(如图中的黄色节点)。反过来,如果圆节点与 GC Roots 不存在可达路径,则意味着这块对象的内存资源不再被程序引用,系统虚拟机可以在 GC 过程中将其回收掉。

从定义上讲,Android(Java)平台的内存泄漏是指没有用的对象资源任与GC-Root保持可达路径,导致系统无法进行回收。

内存泄漏带来的危害

  • 用户对单次的内存泄漏并没有什么感知,但当泄漏积累到内存都被消耗完,就会导致卡顿,崩溃。
  • 内存泄露是内存溢出OOM的重要原因之一,会导致Crash

Android中常见的可能发生内存泄漏的地方


1.在Android开发中,最容易引发的内存泄漏问题的是Context

比如ActivityContext,就包含大量的内存引用,一旦泄漏了Context,也意味泄漏它指向的所有对象。

造成Activity泄漏的常见原因:

  • Static Activities
    在类中定义了静态Activity变量,把当前运行的Activity实例赋值于这个静态变量。
    如果这个静态变量在Activity生命周期结束后没有清空,就导致内存泄漏。
    因为static变量是贯穿这个应用的生命周期的,所以被泄漏的Activity就会一直存在于应用的进程中,不会被垃圾回收器回收。
static Activity activity; //这种代码要避免
  • 单例中保存Activity
    在单例模式中,如果Activity经常被用到,那么在内存中保存一个Activity实例是很实用的。但是由于单例的生命周期是应用程序的生命周期,这样会强制延长Activity的生命周期,这是相当危险而且不必要的,无论如何都不能在单例子中保存类似Activity的对象。
    举例:
public class Singleton {
    private static Singleton instance;
    private Context mContext;
    private Singleton(Context context){
        this.mContext = context;
    }

    public static Singleton getInstance(Context context){
        if (instance == null){
            synchronized (Singleton.class){
         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值