针对图片性能优化的总结
2011-09-18 03:14
246 查看
由于android设备的RAM较小,且Java的GC机制不够智能,经常会出现Out of memory异常。 当然,除了上面的原因,也有可能就是因为写的程序有bug,产生内存溢出。在进行图片较多的软件处理时,很有可能会遇到OOM(out of memory)的异常。
图片是一个非常消耗内存的资源,针对图片的处理需要进行特殊的处理。经过一段时间的调研,我总结出来几个注意事项。
尽量使用9png格式的图片
加载图片时,压缩图片后加载
尽快的手动标记回收图片资源
设置dalivk虚拟机的初始堆内存大小和GC效率(适用于不单单是图片的问题)
调用system.gc来执行垃圾回收(不赞成的方法)
下面是对这几个内容的仔细分析:
尽量使用9png格式的图片
android系统为了提高图片的质量,提高android对各种屏幕的适应能力。系统推出了对.9.png格式图片的支持。这就就可以把一些图片在美工那里就做的非常小,之后还满足了产品对品质的要求。
加载图片时,图片压缩后加载
正常程序中加载图片调用函数:BitmapFactory.decodeFile(imageFile);
为了在加载图片时可以对图片压缩后在加载,对前面的这段代码进行一下加工:
设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,即opts.width和opts.height。有了这两个参数,再通过一定的算法,即可得到一个恰当的inSampleSize。
查看Android源码,Android提供了一种动态计算的方法。
使用该算法,就可动态计算出图片的inSampleSize。然后去设置好inSampleSize后才去加载图片。
尽快的手动标记回收图片资源
在图片资源用完时,尽量手动的去标记一下这些已经用完的图片。帮助GC去识别不用的图片,并回收。
设置dalivk虚拟机的初始堆内存大小和GC效率(适用于不单单是图片的问题)
对于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自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说RAM对 性能的影响十分敏感,除了 优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的对内存大小,我们使用Dalvik提供的 dalvik.system.VMRuntime类来设置最小堆内存为例:
调用system.gc来执行垃圾回收(不赞成的方法)
在以上功能均不能满足条件时,考虑使用该方法。
图片是一个非常消耗内存的资源,针对图片的处理需要进行特殊的处理。经过一段时间的调研,我总结出来几个注意事项。
尽量使用9png格式的图片
加载图片时,压缩图片后加载
尽快的手动标记回收图片资源
设置dalivk虚拟机的初始堆内存大小和GC效率(适用于不单单是图片的问题)
调用system.gc来执行垃圾回收(不赞成的方法)
下面是对这几个内容的仔细分析:
尽量使用9png格式的图片
android系统为了提高图片的质量,提高android对各种屏幕的适应能力。系统推出了对.9.png格式图片的支持。这就就可以把一些图片在美工那里就做的非常小,之后还满足了产品对品质的要求。
加载图片时,图片压缩后加载
正常程序中加载图片调用函数:BitmapFactory.decodeFile(imageFile);
为了在加载图片时可以对图片压缩后在加载,对前面的这段代码进行一下加工:
1 | BitmapFactory.Options opts = new BitmapFactory.Options(); |
2 | opts.inJustDecodeBounds = true ; |
3 | Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts); |
查看Android源码,Android提供了一种动态计算的方法。
01 | public static int computeSampleSize(BitmapFactory.Options options, |
02 | int minSideLength, int maxNumOfPixels) { |
03 | int initialSize = computeInitialSampleSize(options, minSideLength, |
04 | maxNumOfPixels); |
05 |
06 | int roundedSize; |
07 | if (initialSize <= 8 ) { |
08 | roundedSize = 1 ; |
09 | while (roundedSize < initialSize) { |
10 | roundedSize <<= 1 ; |
11 | } |
12 | } else { |
13 | roundedSize =(initialSize + 7 ) / 8 * 8 ; |
14 | } |
15 |
16 | return roundedSize; |
17 | } |
18 |
19 | private static int computeInitialSampleSize(BitmapFactory.Options options, |
20 | int minSideLength, int maxNumOfPixels) { |
21 | double w = options.outWidth; |
22 | double h = options.outHeight; |
23 |
24 | int lowerBound = (maxNumOfPixels == - 1 ) ? 1 : |
25 | ( int ) Math.ceil(Math.sqrt(w *h / maxNumOfPixels)); |
26 | int upperBound = (minSideLength == - 1 ) ? 128 : |
27 | ( int ) Math.min(Math.floor(w / minSideLength), |
28 | Math.floor(h / minSideLength)); |
29 |
30 | if (upperBound < lowerBound) { |
31 | // return the larger one when there is no overlapping zone. |
32 | return lowerBound; |
33 | } |
34 |
35 | if ((maxNumOfPixels == - 1 ) && |
36 | (minSideLength == - 1 )) { |
37 | return 1 ; |
38 | } else if (minSideLength == - 1 ) { |
39 | return lowerBound; |
40 | } else { |
41 | return upperBound; |
42 | } |
43 | } |
//解决加载图片 内存溢出的问题
//Options 只保存图片尺寸大小,不保存图片到内存
BitmapFactory.Options opts =new BitmapFactory.Options();
//缩放的比例,缩放是很难按准备的比例进行缩放的,其值表明缩放的倍数,SDK中建议其值是2的指数值,值越大会导致图片不清晰
opts.inSampleSize = 4;
Bitmap bmp = null;
bmp = BitmapFactory.decodeResource(getResources(), mImageIds[position],opts);
尽快的手动标记回收图片资源
在图片资源用完时,尽量手动的去标记一下这些已经用完的图片。帮助GC去识别不用的图片,并回收。
if(bitmapObject.isRecycled()==false) //如果没有回收 bitmapObject.recycle();
设置dalivk虚拟机的初始堆内存大小和GC效率(适用于不单单是图片的问题)
对于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自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说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去处理
调用system.gc来执行垃圾回收(不赞成的方法)
在以上功能均不能满足条件时,考虑使用该方法。
相关文章推荐
- UITableview性能优化总结—图片加载、行高返回
- 关于图片加载性能优化总结
- Java代码性能优化总结 推荐收藏
- base64:URL背景图片与web页面性能优化
- Java 代码性能优化总结
- 高并发数据库之MySql性能优化实战总结
- .NET 性能优化方法总结
- 前端性能优化:使用媒体查询加载指定大小的背景图片
- Android性能优化系列之Bitmap图片优化
- iOS 性能优化总结
- web前端性能优化总结
- 我们用50次游戏性能的深度优化,总结出了五条“毒鸡汤”
- Spark性能优化总结
- java 35 个 Java 代码性能优化总结
- Java 代码性能优化总结
- 页面加载中的图片性能优化【转】
- git开源库——性能优化——图片缓存
- 35 个 Java 代码性能优化总结
- Actionscrip3.0 性能优化 自己总结