尽量不要使用setimagebitmap或setimageresource或bitmapFactory.decoderesource设置一个大图,因为这些函数最终是通过java层的createbitmap完成的,需要消耗更多的内存。因此,首先通过BitmapFactory改用.decodestream方法,创建bitmap,然后将其设置为imageview source,decodestream最大的秘密是直接调用JNI>>nativeDecodeAsset()完成decode,不需要使用java层的createBitmap,从而节省java层的空间。如果在阅读时添加图片的Config参数,可以有效减少加载内存,从而有效防止抛out of 另外,decodestream直接拿图片读取字节码, 它不会根据机器的各种分辨率自动适应, 使用decodestream后,需要hdpi和mdpi,相应的图片资源配置在ldpi中, 否则,不同分辨率机器的尺寸(像素点数)相同,显示的尺寸是错误的。此外,以下方法也很有帮助:
1.InputStream is = this.getResources().openRawResource(R.drawable.pic1); BitmapFactory.Options options=new BitmapFactory.Options(); options.inJustDecodeBounds = false; options.inSampleSize = 10; //width,hight设置为原来的十分一 Bitmap btp =BitmapFactory.decodeStream(is,null,options);
2.
if(!bmp.isRecycle() ){ bmp.recycle() ////回收图片占用的内存 system.gc() //及时回收提醒系统
以下是一种方法:
/** * 以最省内存的方式读取当地资源的图片 * @param context * @param resId * @return */ public static Bitmap readBitMap(Context context, int resId){ BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; opt.inInputShareable = true; //获取资源图片 InputStream is = context.getResources().openRawResource(resId); return BitmapFactory.decodeStream(is,null,opt); }
================================================================================
Android内存溢出的解决方案
昨天在模拟器上给gallery放图片时,java出现了.lang.OutOfMemoryError: bitmap size exceeds VM budget 异常图像大小超过RAM内存。
模拟器RAM相对较小,只有8M内存,当我放入大量图片(每100K左右)时,就会出现上述原因。
由于每张图片以前都是压缩的,当放入Bitmap时,尺寸会变大,导致超过RAM内存,具体解决方案如下:
//解决加载图片问题 内存溢出问题
//Options 只保存图片的大小,不保存图片到内存
BitmapFactory.Options opts = new BitmapFactory.Options();
///缩放的比例很难按照准备的比例缩放。其值表示缩放的倍数。SDK建议其值为2指数值。值越大,图片就越不清晰
opts.inSampleSize = 4;
Bitmap bmp = null;
bmp = BitmapFactory.decodeResource(getResources(), mImageIds[position],opts);
...
//回收
bmp.recycle();
以上方法解决了,但这并不是最完美的解决方案。
通过一些了解,了解如下:
优化Dalvik虚拟机的堆内存分配
对 对于Android平台,其托管层使用的Dalvik Java 从目前的表现来看,VM还有很多优化处理的地方。例如,在开发一些大型游戏或消耗资源的应用程序时,我们可以考虑手动干预GC处理,使用 dalvik.system.VMRuntime类提供的settargetheaputilization方法可以提高程序堆内存的处理效率。当然具体 我们可以参考开源工程的原理,这里我们只谈使用方法: private final static float TARGET_HEAP_UTILIZATION = 0.75f; 可以在程序oncreate中调用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。
Android堆内存也可以自己定义大小
对于一些Android项目来说,影响性能瓶颈的主要问题是Android自身的内存管理机制。目前,手机制造商对RAM很吝啬,RAM对软件的流畅性也很吝啬 性能的影响非常敏感,除了 除了优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义我们软件的内存大小,我们使用Dalvik提供的Dalvik dalvik.system.以VMRuntime类设置最小堆内存为例:
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); ///设置最小heap内存为6MB大小。当然,对于内存紧张,GC也可以手动干扰
bitmap 设置图片尺寸,避免 内存溢出 OutofmemoryEror的优化方法
★android bitmap中用 内存溢出很容易,报告如下错误:Java.lang.OutOfMemoryError : bitmap size exceeds VM budget
● 主要添加此段:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
● eg1:(通过Uri取图)
private ImageView preview;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;//图片的宽度和高度是原来的两分之一,即图片是原来的四分之一
Bitmap bitmap = BitmapFactory.decodeStream(cr
.openInputStream(uri), null, options);
preview.setImageBitmap(bitmap);
上述代码可以优化内存溢出,但它只能改变图片的大小,不能完全解决内存溢出问题。
● eg2:(通过路径去图片)
private ImageView preview;
private String fileName= "/sdcard/DCIM/Camera/2010-05-14 16.01.44.jpg";
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;//图片的宽度和高度是原来的两分之一,即图片是原来的四分之一
Bitmap b = BitmapFactory.decodeFile(fileName, options);
preview.setImageBitmap(b);
filePath.setText(fileName);
★Android 还有一些性能优化方法:
● 首先,内存可以参考 Android堆内存也可以自己定义大小 和 优化Dalvik虚拟机的堆内存分配
● 在基本类型上,由于Java没有实际的指针,它仍然需要在NDK的帮助下完成敏感操作。Android123提醒游戏开发者,谷歌更有趣 推出NDK可能是为了帮助游戏开发者,比如OpenGL ES的支持有明显的变化,需要本地代码操作图形界面。
● 图形对象优化,这里要说的是Android上的Bitmap对象被销毁,GC可以通过recycle()来回收一个Bitmap对象,通常可以使用以下方法来使用一个不需要的Bitmap,比如
if(bitmapObject.isRecycled()==false) //如果没有回收
bitmapObject.recycle();
● 目前,系统对动画的支持相对较弱。传统应用程序的间隙过渡效果是可以的,但对于游戏来说,一般艺术家可能已经习惯了GIF的统一处理。目前,Android系统只能预览GIF的第一帧,GIF89格式的资源可以通过J2ME中的线程和自写分析器来读取。
● 对于大多数Android手机来说,没有太多的物理按钮,我们可能需要想象手势识别 GestureDetector 以及重力感应来实现控制。通常要考虑误操作的降噪处理。
Android堆内存也可以自己定义大小
对于一些大型Android项目或游戏来说,除了算法处理没有问题外,影响性能瓶颈的主要问题是Android自身的内存管理机制。目前,手机制造商与RAM相比 RAM对软件的流畅性非常敏感,除了上次Android开发网提到的,RAM对性能的影响也非常敏感 除了优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义我们的软件对内存的大小,我们使用Dalvik提供的内存 dalvik.system.以VMRuntime类设置最小堆内存为例:
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); ///设置最小heap内存为6MB大小。当然,对于内存紧张,GC也可以手动干预。下次我们将提到具体的应用程序。
优化Dalvik虚拟机的堆内存分配
对 对于Android平台,其托管层使用的Dalvik 从目前的表现来看,JavaVM还有很多优化处理的地方。例如,我们可以考虑在开发一些大型游戏或资源消耗应用程序时手动干预GC处理,使用 dalvik.system.VMRuntime类提供的settargetheaputilization方法可以提高程序堆内存的处理效率。当然具体 我们可以参考开源工程的原理,这里我们只谈使用方法: private final static floatTARGET_HEAP_UTILIZATION = 0.75f; 可以在程序oncreate中调用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。
介绍图片占用过程中的内存算法。
Bitmap是Android中处理图片的基本类别,顾名思义,就是位图。占用内存的算法如下:
width图片*height*Config。
如果Config设置为ARGB_888,那么上面的Config是4。480*320的图片占用480*320*4的内存 byte。
前面有人说了8M的概念,其实默认情况下android过程的内存占用量是16M,因为除了java中的数据,bitmap是底层C++的。 Skia图形库还将持有Skbitmap对象,因此一般图片占用的内存推荐尺寸不应超过8m。这可以调整,并在编译源代码时设置参数。