Android内存管理及内存泄漏分析(二)

本文深入探讨了Android中的内存泄漏问题,包括Java内存泄漏的特点和C++中的区别,以及Android特有的内存泄漏场景。重点分析了Activity泄漏、静态变量、内部类、匿名内部类、Handler以及资源未关闭等常见原因,并提供了相应的解决策略。此外,文章提到了MAT工具在内存泄漏分析中的重要作用。
摘要由CSDN通过智能技术生成

4、常见内存泄漏

这是一个老生常谈的一个问题了,但我还是先对Java中的内存泄漏做一个定义:

Java中的内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。

在C++中,内存泄漏的范围更大一些。有些对象被分配了内存空间,然后却不可达,由于C++中没有GC,这些内存将永远收不回来。在Java中,这些不可达的对象都由GC负责回收,因此程序员不需要考虑这部分的内存泄露。

对于Java中的内存泄漏,我总结为三点:static、线程 和 系统(外部)资源申请。

对于JVM内部而言,它的垃圾回收机制真的做的非常不错,我总觉得Java的出现是程序员的一次体力解放,大家再也不用去关心那个让RD们睡不好觉的指针问题;而JVM内部的内存泄漏,追究起原因来,我觉得(瞎估的)90%是static静态变量引起的、10%是while(true)的线程造成的,大家想一下,我们平时发现的内存泄漏,是不是大都是注册了监听没释放,或者是声明了一个大对象的static为了方便传递数据,结果忘了置空;对于static这样的变量,我们声明时要非常小心,我的意见是,不是非常必要的情况下,能不用尽量不要用。

外部资源申请一般指的是打开一些文件、设备、数据库等,这些系统都会给我们提供一些开销,如果我们没能及时关闭掉这些设备,则会造成不必要的内存开销。

Android上的内存泄漏会更具体一些,有些也会很隐蔽,我们来具体分析一下,这也是每个Android程序员面试都会考到的一个题。

(1)activity泄漏

这是我们平时最关心的泄漏,因为Activity在Android的四大组件中持的有资源最多,一个Activity没回收,会导致它里面的无数个View都无法被回收到。

<1>在需要Context的地方传入Activity,导致被静态变量持有,这种情况大家应该碰到的很多。

public class AppManager {
    private static AppManager instance;
    private Context context;
    private AppManager(Context context) {
        this.context = context;
    }
    public static synchronized AppManager getInstance(Context context) {
        if (instance == null) {
            instance = new AppManager(context);
        }
        return instance;
    }

....

// 使用时
AppManager am = AppManager.getInstance(activity);

上面这种情况,activity就被静态变量instance持有了,除非appmanager这个单例释放了。

这种情况有两个解决办法:

1、AppManager am = AppManager.getInstance(activity.getApplicationContext()); // 不建议

2、private AppManager(Context context) {
    this.context = context.getApplicationContext();
}

建议使用第二种方法,因为这是从根上进行的解决,而第一种方法是需要调用者来保证解决,这种方法很不靠谱,而且从严格意义上说,调用都使用的根本没错,他传进去的Activity就是一个Context。

&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值