美文网首页Android入门
内存溢出和内存泄漏

内存溢出和内存泄漏

作者: 承影2014 | 来源:发表于2019-08-15 22:03 被阅读0次

    内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

    内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

    memory leak会最终会导致out of memory!

    一,常见的内存溢出情况:
    1,加载图片过大,超出所申请的内存
    解决方法:

    (1)对图片进行压缩处理(不推荐,图片多起来,你再怎么压缩也是要耗很大的内存)

    (2)使用第三方加载图片框架(推荐,开源,省时又省事)Glide ,Picasso ,Fresco等

    (3)减少Bitmap对象的引用,并及时的回收

    2,对象引用没及时回收,导致堆积,超出所申请的内存
    解决方法:

    (1)动态回收内存

    (2)对像引用采用软引用(方便内能够对此进行回收)

    (3)对象复用,存在的对象不要重复多次new它,应该循环利用

    (4)注意对象复用的生命周期(static和程序进程一样长)

    (5)单例模式的合理使用,单例模式避免重复创建对象,但也注意他的生命周期和程序进程一样长容易因为持有的对象没有正常回收导致内存泄漏

    (6)监听器不使用时及时注销

    (7)尽量减少抽象对象的使用

    3,页面持有内存,没有及时回收
    (1)Activity,fragment页面:

        1.Acitvity对静态变量的持有问题
    
        2.页面回收时及时回收Handler消息队列
    
        3.Activity Context 被其他实例持有,导致无法GC
    

    (2)webview页面

        1.及时销毁webView 避免存在进程对内存进行消耗
    

    4,无用服务后台持续运作,占用过多内存
    (1)用完及时关闭

    二,常见的内存泄漏情况:
    1,Handler 引发内存泄漏
    (1)handler发送的Message未被处理,那么该Message及发送它的Handler对象都会被线程一直持有,由于Handler属于TLS(Thread Local Storage)变量,生命周期和Activity是不一致的。如果Handler是我们的Activity类的非静态内部类,Handler就会持有Acitvity的强引用,此时该Activity退出时无法进行内存回收,造成内存泄漏。

    解决方法:

    将Handler声明为静态内部类和软引用,这样它就不会持有外部类的引用了,Handler的生命周期就与Activity无关了。声明时context采用Application的Context,销毁Acitvity时处理掉队列中的消息。

    2,单例模式引发内存泄漏
    (1)单例模式的静态属性,使它的生命周期和应用一样长,如果让单例引用Activity的强引用,Activity无法gc,就会导致内存泄漏。

    解决方法:

    所以在创建单例时,构造函数里对Activity 的context引用换成 ApplicationContext

    3,匿名内部类引起内存泄漏
    (1)activity ,fragment 或者view中使用匿名类,匿名类对象会持有Activity,Fragment,View的引用,如果引用传到异步线程中,异步线程和Activityt生命周期不一致的时候,就会造成Activity的泄漏。

    解决方法:能直接声明内部类引用就减少匿名内部类的引用。尽量不把匿名内部类用到异步线程中去

    4,WebView 引起的内存泄漏
    (1)webview解析网页时会申请Natvie堆内存用于保存页面元素,当页面较复杂时,会有很大的内存占用。如果包含图片,内存占用会更严重,并且打开新页面时,为了能快速回退,之前页面内存也不会释放。或者是退出Activity页面时,webview还在处理网络数据,持有Activity的引用时会导致Activity不能被Gc也会造成内存泄漏。

    解决方法:

    webview采用动态添加,onDestroy时移除,和销毁webview。

    5,集合引发的内存泄漏
    (1)把对象的引用加入集合容器中,当我们不再需要该对象时,并没有把它的引用从集合中清理掉,当集合中的内容过大的时候,并且是static的时候就造成了内存泄漏。

    解决方法:

    在onDestory中清空;

    6,其他引发内存泄漏
    (1)构造Adapter时,没有使用缓存的convertView

    (2)Bitmap在不使用的时候没有使用recycle()释放内存

    (3)线程未终止造成内存泄漏

    (4)对象的注册与反注册没有成对出现造成的内存泄漏;比如注册广播接收器,注册观察者等

    (5)不要在执行频率很高的方法或者循环中创建对象。


    本文整理自以下两篇文章
    原文链接:https://blog.csdn.net/lililijunwhy/article/details/87966337
    原文链接:https://blog.csdn.net/sasafeng/article/details/8559992

    相关文章

      网友评论

        本文标题:内存溢出和内存泄漏

        本文链接:https://www.haomeiwen.com/subject/wwotsctx.html