Android 开发OOM解决方案
OOM(Out Of Memory)在加载图片过多或者过大的情况下会发生OOM,可以查看APP最高可用内存:
int maxMemory = (int) (Runtim.getRuntime().maxMemory()/1024);
OOM问题如何解决?
解决方案:
1、使用强引用(StrongReference)、弱引用(WeakReference)、软引用(SoftReference)、虚引用(PhantomRefrence),在内存引用中做处理。
2、在内存加载图片的时候,在内存中处理图片(边界压缩等)。
3、动态回收内存。
4、优化Dalvik的堆内存分配。
5、自定义堆内存的大小。
下面是对以上几点的详细描述:
1、引用的处理。
Heap中的对象有强可及、软可及、弱可及、虚可及和不可达对象。应用的强弱顺序是强、软、弱、虚。对于对象属于哪种可及对象,由它的最强引用决定。
String abc = new String("abc"); // 建立强引用,内存中abc是强可及,不能释放内存。
SoftReference<String> abcSoftRef = new SoftReference<String>(abc);// 建立软引用,仍然是强可及,不能释放内存。
WeakReference<String> abcWeakRef = new WeakPeference<String>(abc);//建立弱引用,强可及,不能释放内存。
abc = null;// 强引用取消,变成软可及
abcSoftRef.clear();//软引用取消,变成弱可及
总结:
强引用:只能释放没有强引用指向的内存。http://i.cnblogs.com/EditPosts.aspx?postid=5543041
弱引用:当Dalvik内存不足时,可以释放引用指向的内存。
软引用:无条件的执行Dalvik的指令。
虚引用:和以上引用不一样,跟踪引用的释放过程。
2、图片处理
BitmapFactory提供了多个方法decodeFile()解析SD卡中的图片、decodeResource()解析资源文件图片、decodeStream()解析网络图片。
2.1 单一图片压缩
public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int repHeight){
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if(height > reqHeight || width > reqWidth){
final int heightRatio = Math.round((float) height/(float) reqHeight);
final int widthRatio = Math.round((float) width/(float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
public static Bitmap decodeSampleBitmapFromResource(Resource res, int resId,int reqWidth,int reqHeight){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res,resId,options);
}
使用方式:
imageView.setImageBitmap(decodeSampleBitmapFromResouce(getResource(),R.id.myimg,100,100));
压缩流程:
(1)、创建Options对象,将inJustDecodeBounds设置为true.
(2)、解析图片,将属性值赋予options对象。
(3)、计算压缩比例,将比例值赋予options的inSampleSize属性。
(4)、将inJustDecodeBounds赋值false后,重新解析图片,返回Bitmap对象。
2.2 批量图片处理
处理单个照片的如上比较简单,但是一旦遇到批量图片处理,android为我们提供一个类LruCache,用于图片缓存(是一种内存缓存技术)。当缓存图片的数量到达预计设定的值的时候,近期使用比较少的图片会被回收掉。
流程:
private LruCache<String, Bitmap> mMemoryCache;
private void initLurCache(){
//1.设置缓存图片使用的内存大小,程序内存的八分之一。
int cacheMemory = (int) (Runtime.getRuntime().maxMemory()/8);
//2.初始化LruCache实例对象,重写sizeOf()、entryRemoved()方法。
mMemoryCache = new LruCache<String, Bitmap>(cacheMemory){
//必须重写此方法,来测量Bitmap的大小
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
@Override
protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
// TODO Auto-generated method stub
super.entryRemoved(evicted, key, oldValue, newValue);
removeBitmapCache(key);
}
};
}
//3.分别实现清空缓存、添加图片到缓存、获取图片、从缓存移除图片
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null && bitmap != null) {
mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
public void clearCache(){
if (mMemoryCache != null && mMemoryCache.size() > 0) {
mMemoryCache.evictAll();
}
}
public void removeBitmapCache(String key){
if (key != null && mMemoryCache != null) {
Bitmap bitmap = mMemoryCache.remove(key);
if (bitmap!=null) {
bitmap.recycle();
}
}
}
3、动态回收内存
显示调用recycle()方法让GC回收内存。
if(!abc.isRecycled()){
abc.recycle();
}
4、优化Dalvik堆内存分配
使用Dalvik.System.VMRuntime类提供的setTargetHeapUtilization()方法可以增强程序堆内存的处理效率。
private final static float HEAP_UTILIZATION = 0.75f;
//在onCreate()的时候调用
Runtime.getRuntime().setTargetHeapUtilization(HEAP_UTILIZATION);
5、自定义内存
private final static int HEAP_SIZE = 6*1024*1024;
Runtime.getRuntime().setMinimumHeapSize(HEAP_SIZE);
Android 开发OOM解决方案的更多相关文章
- 64位ubuntu搭建android开发环境问题解决方案
安装32位库支持,删除eclipse 的配置文件和.android目录(测试环境ubuntu 14.04) sudo apt-get install libc6-i386 lib32stdc++6 l ...
- Android OOM 解决方案
Out of Memory(内存溢出) 几乎是每个Android程序员都会遇到的事.在网上也能找到一大堆的解决方案,之前写过一篇<Android 内存溢出管理与测试>的博文.但感觉写得不是 ...
- Android开发笔记——图片缓存、手势及OOM分析
把图片缓存.手势及OOM三个主题放在一起,是因为在Android应用开发过程中,这三个问题经常是联系在一起的.首先,预览大图需要支持手势缩放,旋转,平移等操作:其次,图片在本地需要进行缓存,避免频繁访 ...
- Android开发——常见的内存泄漏以及解决方案(一)
0. 前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52333954 Android的内存泄漏是Android开发领域永恒的 ...
- android 帧动画的实现及图片过多时OOM解决方案(一)
一,animation_list.xml中静态配置帧动画的顺序,如下: <?xml version="1.0" encoding="utf-8"?> ...
- Android开发——Android M(6.0) 权限解决方案
Android开发--Android M(6.0) 权限解决方案 自从Android M(6.0)发布以来,权限管理相比以前有了很大的改变,很多程序员发现之前运行的好好的Android应用在Andro ...
- Android开发——View滑动冲突解决方案
0. 前言 我们在Android开发--事件分发机制详解中深入学习了事件分发机制,为我们解决Android开发中的滑动冲突问题做了初步准备.针对滑动冲突这里给出两种解决方案:外部拦截法和内部拦截法 ...
- Android开发——常见的内存泄漏以及解决方案(二)
)Android2.3以后,SoftReference不再可靠.垃圾回收期更容易回收它,不再是内存不足时才回收软引用.那么缓存机制便失去了意义.Google官方建议使用LruCache作为缓存的集合类 ...
- 9种常见的Android开发错误及解决方案
整理总结了9个Android开发中的错误以及解决方案,共同探讨进步! 1. 如果你的项目的R文件不见的话,可以试下改版本号在保存,R文件不见一般都是布局文本出错导致. 2. 布局文件不可以有大写字母 ...
随机推荐
- SpringBoot 教程之 banner 定制
目录 简介 变量 配置 编程 示例 参考资料 简介 Spring Boot 启动时默认会显示以下 LOGO: . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ ...
- vulnhub靶机之DC6实战(wordpress+nmap提权)
0x00环境 dc6靶机下载地址:https://download.vulnhub.com/dc/DC-6.zip dc6以nat模式在vmware上打开 kali2019以nat模式启动,ip地址为 ...
- [USACO19OPEN]Valleys P
题意 洛谷 做法 用并查集维护区域,剩下的就只用判是否有洞就好了 然后手玩出一个结论:凸角为\(+1\),凹角为\(-1\),和为\(sum\),洞数\(h\),满足\(sum=4-4h\) 位置\( ...
- 吴裕雄--天生自然HADOOP操作实验学习笔记:mapreduce和yarn命令
实验目的 了解集群运行的原理 学习mapred和yarn脚本原理 学习使用Hadoop命令提交mapreduce程序 学习对mapred.yarn脚本进行基本操作 实验原理 1.hadoop的shel ...
- IntelliJ IDEA搭建一个简单的springboot项目
一.IDEA 安装包 百度网盘链接:https://pan.baidu.com/s/1MYgZaBVWXgy64KxnoeJSyg 提取码:7dh2 IDEA注册码获取:http://idea.lan ...
- 数据库中间件DBLE学习(一) 基础介绍和快速搭建
dble基本架构简介 dble是上海爱可生信息技术股份有限公司基于mysql的高可用扩展性的分布式中间件.江湖人送外号MyCat Plus.开源地址 我们首先来看架构图,外部应用通过NIO/AIO进行 ...
- Mac中如何搭建Vue项目并利用VSCode开发
(一)部署Node环境 (1)下载适合Mac环境的Node包,点击进入下载页面 (2)安装Node环境:找到下载好的Node包,这里是node-v12.14.1.pkg,我们双击它,会进入Node.j ...
- 【巨杉数据库SequoiaDB】社区分享 | SequoiaDB + JanusGraph 实践
本文来自社区用户投稿,感谢小伙伴的技术分享 项目背景 大家好!在春节这段时间里,由于一直在家,所以花时间捣鼓了一下代码,自己做了 SequoiaDB 和 JanusGraph 的兼容扩展工作. 自己觉 ...
- 【Vue2.x笔记3】从源码看watch对象
初始化 function initWatch (vm: Component, watch: Object) { for (const key in watch) { const handler = w ...
- 订阅消息---由于微信小程序取消模板消息,限只能开发订阅消息
订阅消息开发步骤: 1.小程序管理后台添加订阅消息的模板 2.小程序前端编写调用(拉起)订阅授权 wx.requestSubscribeMessage({ tmplIds: ['34fwe1211xx ...