OOM的一些理解与处理
来源:互联网 发布:c语言 libevent 编辑:程序博客网 时间:2024/04/30 06:02
这两天听说了很多关于OOM的问题,自己也看了看一些大神的见解与描述,关于OOM的原因和几点建议和Android OOM产生原因及如何解决(自己是菜逼有些看不懂),自己总结了一下。
OOM产生原因
Dalvik VM主要管理的内存 Java heap,由于手机设备的限制,一般一个应用使用的内存不能超过默认值 32M(不同设备略有差异,加上手机更新换代较快,现在128M的也有,可以通过adb shell getprop | grep dalvik.vm.heapgrowthlimit命令查看),一个应用进程的内存可以由2个部门组成:java 使用内存 ,C 使用内存 。这也就是说,当在DVM上申请的堆内存大于默认阀值的时候,我们的应用就会抛出OutOfMemoryError 。一旦内存分配给Java后,以后这块内存纵然开释后,也只能给Java的使用,这个估计跟java虚拟机里把内存分成好几块进行缓存的原因有关,反正C就别想用到这块的内存了,所以要是Java突然占用了一个大块内存,纵然很快开释了,C能使用的内存 = 32M - Java某一瞬间占在的最大内存。 而Bitmap的生成是路程经过过程malloc进行内存分配的,占用的是C的内存。也就是说当Java占的内存多了,Bitmap所能占的内存就少了。
如何解决和避免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、解决内存泄露问题
内存泄漏主要是指进程没有及时释放掉没有用的对象,如上面提到的Bitmap没有Recycler()或者Handler对象没有清空等,当进程死掉后仍占着内存,累计多了会造成内存溢出,也就是OOM了(以上是自己的总结,有错请告诉我,与下文无关)。解决该问题主要需要对Android系统各部分组件进行一些较深入了解,比如: 对Activity的生命周期进行了解以后,就应该避免对生命周期之外的引用(其实可以在OnDestroy()方法中释放没用的内存,这也是自己的总结,嘻嘻)。一个应用可能有多个Activity构成,这时候应该考虑使用Application类。(该问题主要是针对Activity中静态对象的控制) 尽量不要由于各种复杂的引用导致GC不能及时的甚至永远不能回收某块内存。
- OOM的一些理解与处理
- 有关OOM的一些处理
- OOM的一些处理方式
- 有关OOM KILLER的一些理解
- Android 的一些基本概念和OOM异常的处理方法
- OOM异常的处理
- 基础知识记录:OOM异常出现的情况与处理方式
- RegionServer与OOM不得不说的一些事儿
- oom处理
- 避免OOM的一些实用的方法
- 如何理解与有效避免安卓加载Bitmap造成的OOM异常
- Linux内核OOM机制的理解
- 温故而知新 - 一些解决OOM的方法
- Android OOM以及GC的一些建议
- Bitmap导致的OOM 一些解决方案
- Android OOM遇见的一些问题
- 一则OOM死机故障的处理过程
- 一则OOM死机故障的处理过程
- Struts2 validation验证失败之后s:select的list返回不了的解决
- 盒子模型
- 用JS改变CSS样式
- python 正则匹配
- 常见设计模式之单例模式(Singleton)
- OOM的一些理解与处理
- SpringMvc注解方式开发入门
- IOS-Frameworks-UIKit-UIView.h-frame属性和bounds属性
- 仿知乎主页,上滑隐藏NavigationBar,下滑显示
- 【BZOJ 2453】【JZOJ 2491】维护队列
- 什么是嵌入式系统
- 设计模式-备忘录模式
- servlet中request的作用域(包括存值和取值)
- Unix环境下的Socket编程