突出一个简单粗暴!Android Activity泄漏问题解决方案

测试跟你说你的XXActivity泄露了,你如何确认是否真的泄漏?给你简单粗暴的解决方案!

测试跟你说你的XXActivity泄露了,你如何确认是否真的泄漏?

确认泄漏后,你又如何定位是哪里的问题导致内存泄漏?

Android日常开发中,内存泄漏的重灾区就是Activity,相信这两个是每个Android开发者都碰到过的问题,遇到这种问题,我们一般都会祭出我们的杀手锏:Dump Java Heap然后MAT静态分析GC链。然后今天我想另辟蹊径,从更简单的角度定位并解决这种问题。

确认泄漏

我们先来看一个抽象的Activity伪代码:

public class LeakActivity extends Activity {

    ComplexLogicA; // 复杂的业务逻辑代码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ComplexLogicB; // 复杂的业务逻辑代码
        LeakLogic; // 引起泄漏的业务逻辑代码
        ComplexLogicC;
        ComplexLogicD;
    }

    @Override
    protected void onResume() {
        super.onResume();

        ComplexLogicE;
        ComplexLogicF;
        ComplexLogicG;
    }

    OtherComplexLogin... // 其他业务逻辑代码
}

 

 如果我们想确认这个Activity是否存在泄漏,只需让其覆盖Object的finalize方法,在里面添加一句Logcat打印:

public class LeakActivity extends Activity {

    ComplexLogicA; // 复杂的业务逻辑代码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ComplexLogicB; // 复杂的业务逻辑代码
        LeakLogic; // 引起泄漏的业务逻辑代码
        ComplexLogicC;
        ComplexLogicD;
    }

    @Override
    protected void onResume() {
        super.onResume();

        ComplexLogicE;
        ComplexLogicF;
        ComplexLogicG;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();

        Log.d("", "====LeakActivity has been recycled!");
    }

    OtherComplexLogin... // 其他业务逻辑代码
}

 

 然后运行你的项目,打开这个Activity,然后按返回,退出Activity,然后通过IDE强制触发一次GC操作:

 (Android Studio)

(Eclipse)

然后查看Logcat,是否有对应的打印,就能确认Activity是否存在内存泄漏了:有打印,则无内存泄漏,无打印则肯定有内存泄漏了!

定位泄漏原因

定位泄漏原因这个就是比较简单粗暴的排除法,首先把所有复杂业务逻辑注视掉,直到内存泄漏现在不存在:

public class LeakActivity extends Activity {

//    ComplexLogicA; // 复杂的业务逻辑代码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

//        ComplexLogicB; // 复杂的业务逻辑代码
//        LeakLogic; // 引起泄漏的业务逻辑代码
//        ComplexLogicC;
//        ComplexLogicD;
    }

    @Override
    protected void onResume() {
        super.onResume();

//        ComplexLogicE;
//        ComplexLogicF;
//        ComplexLogicG;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();

        Log.d("", "====LeakActivity has been recycled!");
    }

//    OtherComplexLogin... // 其他业务逻辑代码
}

 然后再进出一次Activity,触发GC,确认Activity泄漏已经不存在。然后再把业务逻辑一个个补回来,直到泄漏现象重现。

这样我们就能100%的找出泄漏的原因所在。

知识点

这里用到的一个知识点就是Java中Object类的finalize方法。当GC准备回收一个Java Object(所有Java对象都是Object的子类)的时候,GC会调用这个Object的finalize方法。这个方法有点类似于C++中析构函数,本意是让你用来回收一些已经不需要的资源的(主要是针对Native资源)。其实Java日常开发中,并不鼓励依赖于这个方法来实现回收的逻辑,因为如果你重度依赖于finalize的话,finalize本身也有可能造成内存泄漏,但是我们这里只是用来作为是否已经回收的依据,还是可以的。

总结

虽然此方法看起来比较简单无脑,但是简单粗暴啊,也不失为给开发的一种便利的自测方式,不用其他工具就可以快速的确定你这次的需求新增的Activity是否存在泄漏,权当减少自己Bug数的一种方法吧!

最新文章
1客户案例研究:专家安全扫描,守护金融银行小程序安全和私密性 WeTest私有化部署的定制扫描平台让金融银行客户能无成本接入扫描系统并迅速上手使用。客户能方便快捷地根据定制手册进行自助扫描,根据生成的扫描报告,详细洞察漏洞,快速识别并准确定位问题根源。
2客户案例研究:专家渗透测试,洞察电子商务小程序重大交易漏洞 通过WeTest渗透测试服务,某知名零售公司旗下的在线购物类小程序中发现了8处安全风险,我们的安全专家为客户提供了详细的漏洞报告,提供了较为清晰完整的安全加固方案。在回归测试中,中危以上风险均被解决。
3自查小程序4大安全隐患!文末免费赠送小程序安全扫描专业版! 腾讯WeTest现面向小程序开发者开放免费申请使用小程序安全扫描专业版,助您提前发现全面的安全漏洞。扫描文中问卷二维码或点击问卷链接,即可报名参与免费领取活动。
4浅谈渗透测试服务在泛互行业带来的价值 在泛互联网行业中,渗透测试服务对于保障企业的网络安全至关重要。
5云手机卡顿/无特定设备/商店登录受限怎么办?WeTest专有云帮您解决! 公有云满足了大量小微企业、个人的测试需求;随着客户深入使用,也遇到了一系列新问题。本篇将对几个常见问题予以解答
购买
客服
反馈