Android的oom详解

本文详细探讨了Android应用程序中的Out Of Memory (OOM)问题,包括资源对象未关闭导致的内存泄露、作用域差异引起的问题以及内存压力过大三个主要原因。文章提供了避免内存泄露的策略,如正确管理Cursor、避免内部类引用泄漏、使用Application Context、及时回收Bitmap等。此外,还介绍了减小对象内存占用的方法,如使用轻量级数据结构、避免在Android中使用Enum以及减小Bitmap内存占用。最后,讨论了内存对象的重复利用,如复用系统资源、ListView子View复用和Bitmap复用,以及使用LruCache和LruDiskCache进行缓存管理。
摘要由CSDN通过智能技术生成

Android的oom原因

1.资源对象没关闭造成的内存泄露

try catch finally中将资源回收放到finally语句可以有效避免OOM。资源性对象比如:

1-1,Cursor
1-2,调用registerReceiver后未调用unregisterReceiver()
1-3,未关闭InputStream/OutputStream
1-4,Bitmap使用后未调用recycle()

2.作用域不一样,导致对象的泄露

不能被垃圾回收器回收,比如:

2-1,非静态内部类会隐式地持有外部类的引用,
2-2,Context泄露

3.内存压力过大

3-1,图片资源加载过多,超过内存使用空间,例如Bitmap 的使用
3-2,重复创建view,listview应该使用convertview和viewholder

下面针对上面的几个原因说一下避免措施

如何避免oom?

一共三点:

1.避免对象的内存泄露

2.减小对象的内存占用

3.内存对象的重复利用

1.避免对象的内存泄露

内存对象的泄漏,会导致一些不再使用的对象无法及时释放,这样一方面占用了宝贵的内存空间,很容易导致后续需要分配内存的时候,空闲空间不足而出现OOM。显然,这还使得每级Generation的内存区域可用空间变小,gc就会更容易被触发,容易出现内存抖动,从而引起性能问题。

通常来说,Activity的泄漏是内存泄漏里面最严重的问题,它占用的内存多,影响面广,我们需要特别注意以下几种种情况导致的Activity泄漏,service内存泄露和其他内存泄露:

1) 内部类引用导致Activity的泄漏

最典型的场景是Handler导致的Activity泄漏,如果Handler中有延迟的任务或者是等待执行的任务队列过长,都有可能因为Handler继续执行而导致Activity发生泄漏。此时的引用关系链是Looper -> MessageQueue -> Message -> Handler -> Activity。为了解决这个问题,可以在UI退出之前,执行remove Handler消息队列中的消息与runnable对象。或者是使用Static + WeakReference的方式来达到断开Handler与Activity之间存在引用关系的目的。

Activity Context被传递到其他实例中,这可能导致自身被引用而发生泄漏。
内部类引起的泄漏不仅仅会发生在Activity上,其他任何内部类出现的地方,都需要特别留意!我们可以考虑尽量使用static类型的内部类,同时使用WeakReference的机制来避免因为互相引用而出现的泄露。

2)考虑使用Application Context而不是Activity Context

对于大部分非必须使用Activity Context的情况(Dialog的Context就必须是Activity Context),我们都可以考虑使用Application Context而不是Activity的Context,这样可以避免不经意的Activity泄露。、

3)Service引起的内存泄露

典型的是Service忘记关闭,为了避免可以使用IntentService:会自动开一个线程,使用完关闭service

4)BroadCastReceiver引起的泄露

概括一下,避免Context相关的内存泄露,记住以下事情:

比如onReceive方法里执行了太多的操作

5)注意临时Bitmap对象的及时回收

虽然在大多数情况下,我们会对Bitmap增加缓存机制,但是在某些时候,部分Bitmap是需要及时回收的。例如临时创建的某个相对比较大的bitmap对象,在经过变换得到新的bitmap对象之后,应该尽快回收原始的bitmap,这样能够更快释放原始bitmap所占用的空间。

6)注意单例引起的内存泄露

很多内存泄露是由于单例引起的,因为单例

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值