Android OOM产生原因及如何解决

尊重原创,转载请注明出处:Lee http://blog.csdn.net/hnulwt/article/details/44900761

OOM产生原因

OOM产生可能的原因是因为 1、加载大图片导致内存溢出 2、大量内存泄露
OOM产生的本质是什么呢?
Dalvik VM主要管理的内存 Java heap,由于手机设备的限制,一般一个应用使用的内存不能超过默认值 32M(不同设备略有差异,通过adb shell getprop | grep dalvik.vm.heapgrowthlimit命令查看),这也就是说,当在DVM上申请的堆内存大于默认阀值的时候,我们的应用就会抛出OutOfMemoryError
(其实我们会有这样的疑问,明明我的设备内存有1GB或者更大,但是这么一张图就OOM了?为什么会这样,这里有一篇可以让我们明白其中的原因:关于Bitmap分配在native heap还是dalvik heap上的说明。,第10点有说明)。

如何解决和避免OOM

1、解决大图片导致内存溢出

加载多图:

(1)使用软引用、弱引用,当堆内存不足的时候,就可以自动的释放这些缓存的Bitmap对象。

关于软引用的说明:
软引用(SoftReference)是用来设计object-cache的。他在JVM报告内存不足之前会清除所有的软引用,这样以来gc就有可能收集软可及的对象,可能解决内存不足的问题,避免内存溢出。什么时候会被收集取决于gc的算法和gc运行时可用内存的大小。

关于弱应用的说明:看一个例子更容易懂:

String test =new String("aaa");       
WeakReference<String> testWeak = new WeakReference<String>(test);       
test = null;       
System.out.println("before: "+ testWeak.get());       
System.gc();       
System.out.println("after: "+ testWeak.get()); 

结果:
before: aaa
after: null
如果你希望能随时取得某对象的信息,但又不想影响此对象的垃圾收集,那么你应该用 弱应用(Weak Reference)来记住此对象。

(2)使用过的图并且不再使用,可以调用Bitmap.recycle()加速回收。
if (null != bitmap && !bitmap.isRecycled()) {  
    bitmap.recycle();  
}  
(3)考虑使用文件缓存。

整个大图都需要加载:

得到bitmap之前先利用BitmapFactory.Options的inSampleSize的值得到压缩图片。
关键代码:

    // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeResource(res, resId, options); 
    // 调用上面定义的方法计算inSampleSize值, calculateInSampleSize方法自己写,这里不再赘述
    options.inSampleSize = calculateInSampleSize(options.outWidth, options.outHeight, reqWidth, reqHeight);

    options.inJustDecodeBounds = false; 
    Bitmap bmp = BitmapFactory.decodeResource(res, resId, options); 

只加载部分图片

可以考虑在API 10以后引进的BitmapRegionDecoder类,具体使用方式还未研究,源码注释(BitmapRegionDecoder is particularly useful when an original image is large and you only need parts of the image)。

2、解决内存泄露问题

解决该问题主要需要对Android系统各部分组件进行一些较深入了解,比如:
对Activity的生命周期进行了解以后,就应该避免对生命周期之外的引用。一个应用可能有多个Activity构成,这时候应该考虑使用Application类。(该问题主要是针对Activity中静态对象的控制)
尽量不要由于各种复杂的引用导致GC不能及时的甚至永远不能回收某块内存。

以上是我对OOM问题的一些解决方案,如果大家还有其他很好的方式恳请提出来,共同提升。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android OOM(Out of Memory)是一种常见的运行时异常,指的是应用程序内存不足的错误。当应用程序试图使用超过系统分配给它的内存时,就会出现这种异常。这可能是由于应用程序在后台加载大量数据、存储过多的对象或图像,或者由于系统资源管理器分配的内存不足所致。 为了解决Android OOM问题,您可以采取以下几种策略: 1. 优化您的代码以减少内存使用量:使用正确的数据类型,避免创建不必要的对象,限制图像和资源的数量,以及优化后台加载过程等。 2. 回收不再使用的内存:当您的应用程序不再需要使用某些内存时,应该及时回收它们。这可以通过调用垃圾回收器(Garbage Collector)来完成。 3. 避免在主线程上执行耗时操作:如果您的应用程序在主线程上执行耗时操作(如大量数据处理),这可能导致系统资源管理器超载,从而引发OOM异常。应该将这些操作移至后台线程。 4. 使用内存分析工具:内存分析工具可以帮助您识别内存泄漏和无效内存引用等问题,从而避免OOM异常的发生。 5. 配置您的应用程序以适应不同的内存配置:如果您正在开发一个需要大量内存的应用程序,您应该考虑在AndroidManifest.xml文件中配置您的应用程序以适应不同的内存配置。例如,您可以设置您的应用程序需要的最低和最高内存限制。 请注意,解决Android OOM问题是一个复杂的过程,需要您仔细分析和优化您的代码。如果您遇到了OOM问题,建议寻求专业的帮助或与开发社区进行讨论。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值