Android 内存泄漏的解决方案

之前写在开发系统应用的时候发现很多的内存泄漏。下边是我碰到的加网上看到总结的一些内存溢出问题。
1. handler 非静态匿名内部类
2. 非正当使用static
3. 集合中的对象善于清理
4. 单例模式
5. WebView
6. 一些资源类

handler
源码中提到
/*
* Set this flag to true to detect anonymous, local or member classes
* that extend this Handler class and that are not static. These kind
* of classes can potentially create leaks.
*/
意思是说 如果在使用Handler 不是static 修饰的话可能会引起内存泄漏
因为在使用handler 的时候 其本身是一个内部类,在java 中非静态的内部类 会持有外部类的对象,静态的内部类不会引用外部类的对象
如果外部类是Activity,则会引起Activity泄露 。当Activity finish后,延时消息会继续存在主线程消息队列中1分钟,然后处理消息。而该消息引用了Activity的Handler对象,然后这个Handler又引用了这个Activity。这些引用对象会保持到该消息被处理完,这样就导致该Activity对象无法被回收,从而导致了上面说的 Activity泄露。

这里写图片描述

解决方案

 static class  MyHandler extends Handler{
        WeakReference<MainActivity> weakReference ;
        public MyHandler(MainActivity mainActivity) {
            weakReference = new WeakReference<>(mainActivity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            MainActivity mainActivity = weakReference.get();
            mainActivity.toDo(); // 此方法为 你的Acitivity 中的方法
        }
    }
        MyHandler myHandler = new MyHandler(this);

当然还需要做一下处理

当Activity finish后 handler对象还是在Message中排队。 在Activity onStop或者onDestroy的时候,取消掉该Handler对象的Message和Runnable。
这里写图片描述
在Activity remove 相关Runnable 或者相关message 即可

内部类的处理也是一样的(一般不含handler remove 操作)



非正当使用static
当我们的成员变量是static的时候,那么它的生命周期将和整个app的生命周期一致。这必然会导致一系列问题,如果你的app进程设计上是长驻内存的,那即使app切到后台,这部分内存也不会被释放。按照现在手机app内存管理机制,占内存较大的后台进程将优先回收,因为如果此app做过进程互保保活,那会造成app在后台频繁重启。当手机安装了你参与开发的app以后一夜时间手机被消耗空了电量、流量,你的app不得不被用户卸载或者静默。

这里修复的方法是:
不要在类初始时初始化静态成员。可以考虑lazy初始化(延迟加载)。架构设计上要思考是否真的有必要这样做,尽量避免。如果架构需要这么设计,那么此对象的生命周期你有责任管理起来



集合类的处理
我们通常会把一些对象的引用加入到集合容器(比如ArrayList)中,当我们不再需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大。如果这个集合是static的话,那情况就更严重了。所以在退出程序之前,将集合里面的东西clear,然后置为null,再退出程序.这个问题曾出现在一个锁屏的问题(属于系统进程,然后不停往里塞 用完没有及时会后。这个不合理)
解决方案 用完的对象注意回收, 不用集合了remove 所有对象 并将集合置null



单例模式
如果单利模式的对象引用了Activity 恭喜你 准备被你老大批吧, 因为单例是一个静态对象,当你调用的时候进行了初始化它的销毁时间是App 销毁时间, 也就是说它一旦初始化 进程活着它就活着。然后它引用了一个Activity Activity 调用了onDestroy 方法销毁自身的时候内存被单例引用 虽然调用onDestroy ()(这里应该说是执行, 因为Activity 不会主动调用它,finish()方法会最终调它)但是堆中内存并没有被回收。导致内存泄漏,所以这个单例模式要特别小心
解决方案 不要将activity对象关联单例, 引申不要把非static 对象的与static 关联



WebView
Activity 和 WebView 生命周期不一致,当WebView 中加载没有完全(线程没有执行完全) Acitvity 销毁,恭喜又发生内存泄露了,webview 此时还活着 webview 依赖Acitvity 生存,可以说关联着Acitvity , 造成Acitvity 内存不能被回收。
解决方案?给WebView 开独立进程。用完杀当前进程即可。



资源类的回收
bitmap io 等 该主动回收的主动回收 该close 的close

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值