内存溢出,内存泄漏 两者关系?什么情况下会出现?如何避免避免?

内存溢出(OOM):

是指指程序在申请内存,没有足够的内存供其使用,出现 out of memory ;

内存泄漏(memory leak): 

是指程序在申请内存后,无法释放已申请的内存空间;危害不在于一次性的内存泄漏,而是多次内存泄漏,消耗完所有申请的内存,导致程序无法对其他操作进行内存分配

两者关系

两者是不同的概念,内存泄漏可引起内存溢出(内存泄漏堆积需要到的内存就超出了程序申请到的内存,就会出现内存溢出)

一,常见的内存溢出情况:

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)不要在执行频率很高的方法或者循环中创建对象。

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值