解决OOM小记
跟猜想的一样是OOM.一回来遇一不怎么熟悉的sb,给我气的....算了.....哥哥也是种种原因回的合肥.继续看问题.
这个地方的界面是这样的
划红线的地方是三个LinearLayout,每次onclick会PopupWindow一个界面用来提示用户.
在加载第二次弹出的PopupWindow时候出现了oom
我们来看下图片的大小
这三张图片原本大概在350KB左右,现在100多KB已经是经过压缩的了.
但是我们还是从基本开始搞,转jpg吧.
我们再去试一下,Note3已经没有问题了
如果单单是工作,到这也就结束了,但是老子气的要死,还是继续研究下去.
那我们来算一下大致在手机会占用多少内存吧.
bmp: 以高质量保存 用于计算机
jpg: 以良好的质量保存 用于计算机或者网络
png: 以高质量保存 用于计算机或者网络
图片的大小 = 图片的总像素 * 每个像素的大小
单色 :每个像素最多表示2种颜色 那么只需要一个长度为1的二进制位来表示 那么1个像素占1/8个byte
16色 :每个像素最多可以表示16种颜色, 0 - 15 0000-1111 那么只需要使用一个长度为4的二进制位来表示 那么一个像素占 1/2
256色 :每个像素最多可以表示256种 0-255 0000 0000-1111 1111 只需要使用一个长度为8的二进制位来表示 那么一个像素占1byte
24位 :R 1 byte 0 - 255
:G 1 byte 0 -255
:B 1 byte 0 -255 那么一个像素占3个byte
jpg:类似 rar压缩
png:也会按照特殊的算法进行压缩
我们在xml布局里面是这样写的
默认为ARGB_8888模式需要4个字节
第二次点击出现OOM的popup_two图片详细信息
那么他的内存占用大小为 图片的大小 = 图片的总像素 * 每个像素的大小
1080*1860*4=8035200字节
而报错的是8035212 多出来12个字节是保存图片信息的数据
那么换算成兆字节也就是7.6629639兆字节(mb)
那么再看
当这个图片加载到内存的时候为8035212 字节也就是7.6629639兆字节(mb)超出剩余的6498924空闲字节大小和6MB的head内存.然后内存溢出了.
那么说了那么多,虽然上面已经解决了问题,但是在这之外,我们还能做点什么呢?
1.布局中去android:background和android:src这些属性实际调用的是view.setBackgroundResource和view.setImageResource方法,这两个方法实际上是拿到资源ID再去获取资源的drawable。他们会decode图片后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。
实际上我们可以用decodeStream来替代,因为decodeStream直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间.另外我们可以设置图片的参数,例如设置为Bitmap.Config.RGB_565来减少内存开销。因为在android文档中描述Bitmap.Config.RGB_565每一个像素存在2个字节中,而默认的Bitmap.Config.ARGB_8888每一个像素则需要4个字节,理论上足足节省了一半空间。
布局文件中的android:background去掉,在java文件中来设置背景。
如下:
BitmapFactory.Options opt = newBitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
//获取资源图片
InputStream is = context.getResources().openRawResource(resId);
Bitmap bitmap = BitmapFactory.decodeStream(is,null, opt);
is.close();
returnnew BitmapDrawable(context.getResources(),bitmap);
2.缩放加载大图
iv = (ImageView) findViewById(R.id.iv);
//(1)获取手机的宽和高 windowmanager
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
screenWidth = wm.getDefaultDisplay().getWidth();
screenHeight = wm.getDefaultDisplay().getHeight();
//创建一个位图的配置参数
BitmapFactory.Options opts = new Options();
//不去真正的解析位图 返回no bitmap 但是能获取到图片的宽和高
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile("/mnt/sdcard/xxx.jpg", opts);
//(2)获取图片的宽度 和高度
int imgWidth = opts.outWidth;
int imgHeight = opts.outHeight;
System.out.println("图片的imgwidth:"+imgWidth+"-----"+imgHeight);
//(3)计算缩放比
int scale = 1;
int scalex = imgWidth / screenWidth;
int scaley = imgHeight / screenHeight;
if (scalex >=scaley && scalex >1) {
scale = scalex;
}
if (scaley > scalex && scaley >1) {
scale = scaley;
}
System.out.println("缩放比:"+scale);
//(4)按照真正计算出来的缩放比 进行显示图片
opts.inSampleSize = scale;
//(5)真正的加载位图
opts.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/xxx.jpg", opts);
//(6)把bitmap显示到图片上
iv.setImageBitmap(bitmap);
3.适度回收
if(bitmapObject.isRecycled()==false){ //如果没有回收
bitmapObject.recycle();
System.gc();
}
4.自定义最小head内存大小
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
//设置最小heap内存为6MB大小
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);
5.使用软引用了.
好了,气也消了,不写那么多了,其实工作只要正常跑起来基本问题就没什么了,只是偶尔回顾下基础知识对以后还是有帮助的.
解决OOM小记的更多相关文章
- Android项目实战(十二):解决OOM的一种偷懒又有效的办法
在程序的manifest文件的application节点加入android:largeHeap=“true” 即可. 对,只需要一句话! 那么这行代码的意思是什么呢? 简单的说就是使该APP获取最大可 ...
- 什么是java OOM?如何分析及解决oom问题?
最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说清的,因此按照自己的理解整理了一篇,剩下的还需要 ...
- 什么是OOM?如何解决OOM问题!
1.什么是OOM? 程序申请内存过大,虚拟机无法满足我们,然后自杀了.这个现象通常出现在大图片的APP开发,或者需要用到很多图片的时候.通俗来讲就是我们的APP需要申请一块内存来存放图片的时候,系统认 ...
- Android下缓存以及解决OOM问题
1 http://my.oschina.net/ryanhoo/blog/93285 开篇来个简单的后续的慢慢补充 2 http://www.apkbus.com/forum.php?mod=view ...
- eclispe中解决OOM问题
-Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m
- Android ImageSwitcher 配合Picasso解决内存溢出(OOM)问题
最近项目中用到了 ImageSwitcher 来实现图片切换,使用起来很简单,但发现当图片比较大(超过了3M)时,程序出现了内存溢出(OOM)问题而崩溃了. 原因就是图片太大了,显示到 ImageVi ...
- 一站式解决,Android 拍照 图库的各种问题.
在android开发中, 在一些编辑个人信息的时候,经常会有头像这么一个东西,就两个方面,调用系统相机拍照,调用系统图库获取图片.但是往往会遇到各种问题: 1.oom 2.图片方向不对 3.activ ...
- viewPager--viewpager时,发生内存溢出OOM问题
两个问题:1.如果图片达到500kb每张,你这个划屏会有顿卡:2.快速滑动有出现0.几秒的白屏.图片越大,顿卡越明显. 回复parcool:500kb的背景算大的了,如果是想做图片墙,viewpage ...
- Java 如何有效地避免OOM:善于利用软引用和弱引用
Java 如何有效地避免OOM:善于利用软引用和弱引用 想必很多朋友对OOM(OutOfMemory)这个错误不会陌生,而当遇到这种错误如何有效地解决这个问题呢?今天我们就来说一下如何利用软引用和弱引 ...
随机推荐
- Cookie的Domain
每个Cookie都有常用的几个元素:name.value.expires.domain Cookie的Domain 设置cookies时,可以设置cookie的域名参数domain,标识cookie在 ...
- asp.net基础
这篇主要讲述以下基础知识: Request对象 Response对象 Server对象 Cookie对象 Application对象 ViewState对象 <%%>与<%=%> ...
- 【JS】Intermediate3:AJAX
1.load new content into a page without a full reload XML HTTP Request (XHR) To retrieve new content ...
- Esper系列(二)时间窗口、长度窗口、cast、注解、自定义函数、静态方法
长度窗口实现原理图 说明: 上图长度窗口为5,事件W1至W5进入引擎后属于NewEvents队列,事件W6进入引擎后,W2至W6就属于NewEvents队列,而事件W1就属于OldEvents队列了. ...
- deep learning(1)BP神经网络原理与练习
具体原理参考如下讲义: 1.神经网络 2.反向传导 3.梯度检验与高级优化 看完材料1和2就可以梳理清楚bp神经网络的基本工作原理,下面通过一个C语言实现的程序来练习这个算法 //Backpropag ...
- HDOJ-ACM1021(JAVA)
题意: 斐波拉契数列的另外一个变型,如果F(n)能被3整除,则输出yes,否则输出no.(n<1000000) 解题思路: 看到(n<1000000)这个条件,有点感觉递归量有点大,因此要 ...
- Error message “Assembly must be registered in isolation” when registering Plugins in Microsoft Dynamics CRM 2011 2013 解决办法
Error message “Assembly must be registered in isolation” when registering Plugins in Microsoft Dynam ...
- SignalR Supported Platforms -摘自网络
SignalR is supported under a variety of server and client configurations. In addition, each transpor ...
- 64位linux安装android sdk的问题
截至到今天,似乎在64位机器下安装android sdk存在不能运行的问题,可以用以下方法解决: Android SDK requires: Fedora 17 64bit with 32bit An ...
- nyoj 678 最小K个数之和
最小K个数之和 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 输入n个整数,输出其中最小的K个数之和.例如输入4,5,1,1,6,2,7,3,3这9个数字,当k=4 ...