内存泄露初见

来源:互联网 发布:最好的数据恢复 编辑:程序博客网 时间:2024/05/29 12:04

根据百度百科,内存泄露的意思:指已经动态分配出去的堆内存,无法释放,进而导致程序卡顿甚至崩溃等严重后果。

其具有隐蔽性、积累性;崩溃偶然,并且无具体报错语句指明。内存泄露产生的根本原因是内存块未被释放,属于遗漏型缺陷而非过错型缺陷。
笔z认为,在android中,内存泄露发生归根到底就是生命周期不匹配的问题,命长的持有着命短的。

举个很形象的例:
有个很大的’茅坑’,’村长’把他铲平了作其他用途,这时候一个’老不死’的过来说:“我还要用它的,你不能把他收走。”,村长也无可奈
何,就走了,茅坑继续占用着村地。

村长:GC垃圾回收
茅坑:耗资源的对象…
老不死:持有耗资源对象的对象…

GC想要回收这个耗资源的对象,结果因为有个生命周期很长的对象一直持有他,使得内存始终无法处理,未回收的没茅坑多了,村里就开始崩溃了,就是这么回事!

常见的发生内存泄露的原因:
1:context上下文的错误传参:
把Activity作为上下文传递给静态成员持有,例如:

public void Util{    pruvate Util util;    public void getInstance(Context context){        if(util == null){            util = new Util(context);        }    }}

此时该Activity无法被回收,因为静态的生命周期跟程序一致。要注意,能用Appication的地方,就不要用Activity。
2.创建了静态的非静态内部类对象:
例如:

public class OutActivity{    public static InterClass staticInterClass;    @Override    protected void onCreated(Bundle savedInstanceState{        staticInterClass = new InterClass();    }    class InterClass{}}

这是因为非静态内部类会持有外部类的引用,总的来说,还是static的老不死占着茅坑。可以把内部类改为静态的,或者不要用内部类。
3.Handler:
在使用Handler的时候要注意,Message中是持有Handler的,而Handler是持有其外部Acitivity的,那么当存在未处理的Message时,在同一条绳子上的都不能被回收
4:资源未关闭:
注意使用流、Bitmap,Map、File、Cursor等等要记得手动回收或关闭
5:使用ActivityManager:(笔z遇到,找了一个下午)
在BaseActivity中只记得在onCreate中add进去,却忘记在onDestroy中pop出来
6.多线程
如果子线程开启任务并持有该Acitivity时,当actiivity退出,子线程却未执行完,那么activity还无法被回收

最近在做项目的过程中终于遇到内存溢出、内存泄露这些问题了,以前只是知道有这个东西,却从未在开发中遇到过,并且,文字如果过大也会引起,可不只是图片那些哦,开发中可以使用LeakCanary来帮助寻找问题。

大概就总结到这里了,开始学vue做项目了,好好加油!

原创粉丝点击