内存泄漏与内存溢出

一 什么是内存泄漏与内存溢出

内存泄漏: 在Java中有些对象的生命周期是有限的,当它们完成了特定的逻辑后将会被垃圾回收;但是,如果在对象的生命周期本来该被垃圾回收时这个对象还被别的对象所持有引用,那就可能导致内存泄漏。

内存溢出:JVM虚拟机内存耗尽,无法为新对象分配内存,导致APP崩溃。

二 内存泄漏与内存溢出之间的关系

  例如图片的加载


当某个界面存在内存泄露,反复进入该界面,将导致一直有新对象创建但是无法回收,最终内存耗尽,产生内存溢出。

三 哪些情况容易导致内存泄漏

  • 资源释放问题 
    程序代码的问题,长期保持某些资源,如Context、Cursor、IO流的引用,资源得不到释放造成内存泄露。
  • 对象内存过大问题 
    保存了多个耗用内存过大的对象(如Bitmap、XML文件),造成内存超出限制。
  • static关键字的使用问题 
    static是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例(Context的情况最多),这时就要谨慎对待了。 
    针对static的解决方案: 
    1) 应该尽量避免static成员变量引用资源耗费过多的实例,比如Context。 
    2) Context尽量使用ApplicationContext,因为Application的Context的生命周期比较长,引用它不会出现内存泄露的问题。 
    3) 使用WeakReference代替强引用。比如可以使用WeakReference mContextRef;
  • 线程导致内存溢出 
    线程产生内存泄露的主要原因在于线程生命周期的不可控。 
    针对这种线程导致的内存泄露问题的解决方案: 
     将线程的内部类,改为静态内部类(因为非静态内部类拥有外部类对象的强引用,而静态类则不拥有)。 
     在线程内部采用弱引用保存Context引用。

  • 查询数据库没有关闭cursor 
    程序中经常会进行查询数据库的操作,但是经常会有使用完毕Cursor后没有关闭的情况。如果我们的查询结果集比较小,对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会出现内存问题,这样就会给以后的测试和问题排查带来困难和风险。

  • 构造Adapter没有复用convertview 
    在使用ListView的时候通常会使用Adapter,那么我们应该尽可能的使用ConvertView。 
    为什么要复用convertView? 
    当convertView为空时,用setTag()方法为每个View绑定一个存放控件的ViewHolder对象。当convertView不为空,重复利用已经创建的view的时候,使用getTag()方法获取绑定的ViewHolder对象,这样就避免了findViewById对控件的层层查询,而是快速定位到控件。

  • Bitmap不再使用时没有调用recycle()释放内存

       有时我们会手工的操作Bitmap对象,如果一个Bitmap对象比较占内存,当它不再被使用的时候,可以调用Bitmap.recycle()方法回收此对象的像素所占用的内存,但这不是必须的,视情况而定。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值