内存优化之内存泄漏

1.为什么会导致内存泄漏?

        长生命周期持有对短生命周期对象的引用,导致对无用对象的引用一直未被释放,就会导致内存泄漏-----比如你按back键关掉了一个Activity,那么这个Activity页面就暂时没用了。但是某个后台任务如果一直持有着对该Activity对象的引用,这个时候就会导致内存泄露。

2.常见的内存泄漏

        2.1->Activity内存泄漏

        2.1.1->内部类导致的泄漏.内部类实例会隐式的持有外部类的引用。

                A->Thread线程导致的内存泄漏:在Activity中创建一个内部类去继承Thread,然后让该Thread执行一些后台任务,未执行完时,关闭Activity,此时会内存泄露.

                解决方案1:将内部类改为静态内部类.

                          2:使用弱引用或者软引用的方式,来引用外部类,如图:


              B->Handler导致的内存泄漏:内部类Handler会拿着外部类Activity的引用,而那个Message又拿着Handler的引用。这个Message又要在消息队列里排队等着被handler中的死循环来取消息。从而形成了一个引用链,最后导致关于外部类Activity的引用不会被释放。

                解决方案:3:更完美的做法是在之前两种基础上面,在当Activity页面退出时,将handler中的所有消息进行移除.如下:

C->非静态内部类的静态实例:非静态的内部类创建了一个静态实例。非静态内部类会持有外部类Activity的引用,后来又创建了一个这个内部类的静态实例。这个静态实例不会在Activity被关掉时一块被回收(注:静态实例的生命周期跟应用的生命周期一样长)。

                解决方案:1:将内部类设置为静态内部类.

        2.2->Context导致的内存泄漏

                有时候我们会通过静态的方式去引用一个Activity。比如:创建一个以单例的形式存在的类,因为静态实例比Activity生命周期长,你在使用静态类时将Activity作为context参数传了进来,即使Activity被关掉,但是静态实例中还持有队它的使用,所以会导致Activity没法被及时回收,造成内存泄露。

                解决方案:在传Context上下文参数时,尽量传跟Application应用相同生命周期的Context。比如getApplicationContext(),因为静态实例的生命周期跟应用Application一致。

        2.3->补充关于Context作用域的问题

        2.4->监听器的注销:在Android程序里面存在很多需要register与unregister的监听器,我们需要确保在合适的时候及时unregister那些监听器。自己手动add的listener,需要记得及时remove这个listener。比如说:广播接收者BroadcastReceiver、EventBus等。

        2.5->Cursor对象和IO流是否及时关闭

        2.6->WebView的泄漏:Android中的WebView存在很大的兼容性问题,不仅仅是Android系统版本的不同对WebView产生很大的差异,另外在不同手机厂商出货的ROM里面,WebView也存在着很大的差异。所以通常根治这个问题的办法是为展示WebView的页面开启另外一个进程,通过AIDL与主进程进行通信,WebView所在的进程可以根据业务的需要选择合适的时机进行销毁,从而达到内存的完整释放。


























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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值