andorid 检测内存泄露及解决办法

声明:本文内容来源于 的汇总:Android性能优化之利用LeakCanary检测内存泄漏及解决办法 - 总李写代码 - 博客园 和 Android性能优化_wall0920的技术博客_51CTO博客,向作者表示感谢

内存泄露和内存溢出

1.有些对象只有有限的生命周期。当它们的任务完成之后,它们将被垃圾回收。如果在对象的生命周期本该结束的时候,这个对象还被一系列的引用,这就会导致内存泄漏。随着泄漏的累积,app将消耗完内存。

2.内存溢出是App为1个对象申请内存空间,内存空间不足的情况.out of memory.

内存泄露造成的影响

它是造成应用程序OOM的主要原因之一。由于android系统为每个应用程序分配的内存有限,当一个应用中产生的内存泄漏比较多时,就难免会导致应用所需要的内存超过这个系统分配的内存限额,这就造成了内存溢出而导致应用Crash。

常见内存泄露案例

1)错误使用单例造成的内存泄漏

Q:而在开发中单例经常需要持有Context对象,如果持有的Context对象生命周期与单例生命周期更短时,或导致Context无法被释放回收,则有可能造成内存泄漏

A:要保证Context和AppLication(getApplicationContext())的生命周期一样

2)Handler造成的内存泄漏

Q:通过内部类的方式创建mHandler对象,此时mHandler会隐式地持有一个外部类对象引用这里就是MainActivity,当执行postDelayed方法时,该方法会将你的Handler装入一个Message,并把这条Message推到MessageQueue中,MessageQueue是在一个Looper线程中不断轮询处理消息,那么当这个Activity退出时消息队列中还有未处理的消息或者正在处理消息,而消息队列中的Message持有mHandler实例的引用,mHandler又持有Activity的引用,所以导致该Activity的内存资源无法及时回收,引发内存泄漏

A:要想避免Handler引起内存泄漏问题,需要我们在Activity关闭退出的时候的移除消息队列中所有消息和所有的Runnable。上述代码只需在onDestroy()函数中调用mHandler.removeCallbacksAndMessages(null);就行了

3)线程造成的内存泄漏

Q:AsyncTask在处理耗时的操作时,可能还没处理结束Activity就执行了退出操作,但是此时AsyncTask依然持有对MainActivity的引用就会导致MainActivity无法释放回收引发内存泄漏。

A:在使用AsyncTask时,在Activity销毁时候也应该取消相应的任务AsyncTask.cancel()方法,避免任务在后台执行浪费资源,进而避免内存泄漏的发生。

 4)非静态内部类创建静态实例造成的内存泄漏

 5)由WebView引起的内存泄漏

 6)资源未关闭造成的内存泄漏

性能优化

1)过度绘制

Q:Overdraw过度绘制是指屏幕上的某个像素在同一帧的时间内被绘制了多次.过度绘制会大量浪费CPU及GPU资源/占用CPU和GPU的处理时间

  • 过度绘制的原因
    1. UI布局存在大量重叠
    2. 非必须的背景重叠.
  • 如Activity有背景,Layout又有背景,子View又有背景.仅仅移除非必要背景就可以显著提升性能.
    1. 子View在onDraw中存在重叠部分绘制的情况,比如Bitmap重叠绘制

A:解决办法

  1. 移除XML布局文件中非必要的Background
  2. 保持布局扁平化,尽量避免布局嵌套
  3. 在任何时候都避免调用requestLayout(),调用requestLayout会导致该layout的所有父节点都发生重新layout的操作
  4. 在自定义View的onDraw中避免过度绘制
  5. 尽量减少每次重绘的元素可以极大提升性能,可以把复杂的View拆分会更小的View进行组合,在需要刷新界面时候仅对指定View进行重绘.
  6. 可以使用include标签引入其他布局文件中,尤其当出现比较通用的view的时候,比如自定义的标题栏或底部菜单栏

2)如何避免OOM

  1. 减小对象的内存占用
  2. 内存对象复用防止重建
  3. 避免使用枚举,用注解替代
  4. 减小创建的Bitmap的内存,使用合适的缩放比例及解码格式 例如:inSampleSize:缩放比例;decode format:解码格式 
  5.  对象池技术:减少频繁创建和销毁对象带来的成本,实现对象的缓存和复用
  6. 尽量使用Android系统内置资源,可降低APK大小,在一定程度降低内存开销
  7. 在for循环中,用StringBuilder代替String实现字符串拼接
  8. 资源对象要及时关闭
  9. Context:尽量使用Application Context而不是Activity Context,避免不经意的内存泄漏

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值