关于OOM的原因和几点建议


基于Android开发应用时,可能会时常出现Out Of Memory 异常。在被这个问题困扰的时候先得了解一下原因,重点当然是需要知道如何处理。
  1、OOM的具体原因。
①一个进程的内存可以由2个部门组成:java 使用内存 ,C 使用内存 ,这两个内存的和必需小于16M,不然就会出现各人熟悉的OOM。
②一旦内存分配给Java后,以后这块内存纵然开释后,也只能给Java的使用,这个估计跟java虚拟机里把内存分成好几块进行缓存的原因有关,反正C就别想用到这块的内存了,所以要是Java突然占用了一个大块内存,纵然很快开释了,C能使用的内存 = 16M - Java某一瞬间占在的最大内存。
③而Bitmap的生成是路程经过过程malloc进行内存分配的,占用的是C的内存。
根据这个原理那么我们就可以有效的避免OOM的出现,具体我们可以做以下一些额外的工作来有效避免OOM。

  2、几点建议。
①对于java中不再使用的资源需要尽快的释放,即设置成null,不要老是指望垃圾回收器为你工作。如果不设置成null,那么资源回收会受到一定的影响。
②尽量少用static方法和static成员。因为static的方法或成员被外部使用的话,而外部的牵引对象没有对其进行释放的话那么整个static的类都不会被释放,也就造成内存泄漏。
③对于不再使用的bitmap应该手动调用recycle方法,并且设置成null。图片还要尽量使用软引用方式,这样可以加快垃圾回收。

  3、一些不恰当的处理。网上也有些其他的处理方式,但总的来说个人觉得不太恰当。如:
①给图片设置option,相对于压缩图片。个人觉得不可取。很多情况下图片本来就不够清晰,经过压缩之后质量上有很大的问题,这还得看个人的取舍。
②更改app的heapsize大小。个人觉得这也不可取。这根本不是从本质上解决问题,因为OOM可能是你某处导致的内存泄露,这样做只是推迟了OOM发生,一定程度上降低了OOM发生率(因为可能在还没有达到heapsize最大值的时候就发生了GC)。android系统他有默认的heapsize的值,至于我们重新设置一个更大的会对整个系统或者其他应用造成什么样的影响其实都是不可知的,所以还是用默认的。
  总结:总的来说在代码实现的过程中,每个环节都有可能是导致OOM的罪魁祸首,只是在图片解码的过程中体现出来了而已。所以在整个编码过程中应该采用一些比较好的编码方式,有时需要对程序进行多次优化来减少内存开销。Java的垃圾回收机制某种程度上给我们带了方便,但是在嵌入式方面还有一些不足,毕竟嵌入式的资源是非常珍贵的,一旦控制不好就会出现OOM。做代码优化之前我们也需要深入理解垃圾回收机制,这样才能有效的控制内存消耗。

发布了8 篇原创文章 · 获赞 7 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/liu31187/article/details/19834687