在之前我们开发游戏一般都只是创建桌面应用程序,而不必去太多关注内存和CPU的使用,因为电脑的基本配置就可以胜任程序的运行。但是在将我们写好的桌面应用程序发布到手机上时,基本上会卡死。因为虽然我们最新的手机iPhone及Android提供了相当高的处理器及更多的内存,但是相比电脑上运行应用程序仍然是小巫见大巫。那么如何才能提高应用程序对内存及CPU的消耗呢?
通常摆在我们所有程序猿面前的一个问题是:我们在编程时应该更关注那一个问题——内存还是CPU资源?因为这两者往往是不可能同时达到的。
下面我们就通过:1.重用对象;2.缓存位图;3.优化帧速率;4.使用GPU渲染,这四个方面来优化内存和CPU使用。
一、重用对象
我们在处理对象时往往是创建并移除他们,但是任何时候实例化一个对象代价是相当大的,但是如果我们很方便的使用对象池来实现对象的重用,则会大大提高其使用效率。
1.使用条件:应用程序需要不断地创建并处理对象,这是我们可以考虑使用对象池。
2.原理:当创建对象池时,在应用程序启动时将会创建一起对象,这样应用程序不需要再创建新对象,而是从对象池中请求并使用它们。当应用程序完成处理这些实例之后,它将停止使用并删除对它们的引用,但是并不将他们设置为null,这时已经对象返回对象池中,便于以后的使用。
3.示例对象池,在以后程序中使用时就可以直接使用并重用其中的对象。
package { import com.zxh.animal.Dog;//狗对象的封装类public final class DogPool{ private static var _pool:Vector.<Dog>;//创建一个狗的对象数组作为对象池 private static var _maxCount:int;//对象最大数目 private static var _counter:int; private static var _growthValue:int;//增加的数目 public static function initinitialCount:int , growthValue:int):void{ var i:int = initialCount; //设置相关属性 _maxCount = initialCount; _counter = initialCount; _growthValue = growthValue; //创建对象池,其中含有initalCount个对象 _pool = new Vector.<Dog>initialCount); //创建Dog对象 while --i > 0){ _pool[i] = new Dog); } } public static function getDog):Dog{ var i:int = _growthValue; if _counter > 0){ return = _pool[ --_counter]; } while --i > 0){ _pool.unshift new Dog)); } _counter = _growthValue; return getDog); } public static function disposeDogdog:Dog):void{ _pool[ _counter++ ] = dog; } } }
二、缓存位图
在手机应用程序中渲染图形的第一原则是尽可能缓存一切内容,重新绘制的开销更大,因此只有在必要的时候才进行渲染。
缓存位图需正确理解和使用以下三种属性:1.cacheAsBitmap;2.cacheAsSurface;3.cacheAsBitmapMatrix。
1.cacheAsBitmap:
a.功能:缓存屏幕外位图,使得可以重复使用它而不需要多次重建位图。消除了渲染现实对象的需求。
b.何时使用(=true):对于不需要应用变换效果的现实对象启用。
c.何时避免启用:如果需要改变现实对象的alpha属性、旋转、缩放等操作时,不必使用该属性。
如果现实对象的内容频繁改变,则不必使用该属性。
2.cacheAsSurface:
a.功能:忽略了重新渲染现实对象的需求。矩阵变换,例如缩放和旋转,应该应用现在缓存对象的外部,而不应该实现为缓存对象的子对象。如果这样GPU(Graphical
Progress Unit,图形处理单元)将处理它。
b.何时使用(=true):对于需要在其上应用变换的现实对象启用。如果在容器现实对象内部动画其他现实对象,则应该对容器现实对象启用。
c.何时避免使用:如果现实对象的内容频繁改变或现实对显的衍生对象也频繁改变,则不要使用该属性。
3.cacheAsBitmapMatrix:
a.功能:缓存x、y、旋转、缩放和偏斜属性。
b.何时使用(=true):适用于非定期更新的现实对象。
c.何时避免使用:如果要修改alpha、颜色属性或者子sprite矩阵,则不需要使用该对象。因为它不仅需要绘制,同时还需要缓存,这样讲减慢渲染速度。
三、优化帧速率
一般情况下我们需要尽可能的降低帧速率,确保性能最优。即设置Stage.framRate(在Flex中设置WindowsApplication.framRate)
设置规则:1.如果程序内部没有使用动画,择其速率一般为4~12帧。
2.如果程序内有动画,则使用20~30帧,但不要超过30帧。
3.如果程序运行视频,则不必调整速率,视频将会接管这速率,自己调整到最佳。就算我们人为地设置改变其速率也没有效果。
四、GPU渲染
不管我们再Android或者iPhone平台上运行应用程序,其都支持GPU硬件加速,GPU处理图形渲染可以很大程度的提高性能。
启用GPU渲染我们必须在应用程序的配置文件(应用程序名.xml)中设置其renderingMode属性设置为gpu,如下:
<renderMode>gpu</renderMode>
但是我们必须知道启用GPU渲染能够处某些特定的任务,但是也不会处理一些其他特定的任务。
GPU不支持如下的操作:
1.滤镜
2.PixelBender(Pixel Bender是Adobe推出的一个高性能的图像视频处理技术。它能跨平台地使用CPU, GPU来对图像和视频应用滤镜和效果,在不了解底层硬件的前提下,我们也可以利用它实现自己的图像处理算法,并良好地运行在各种不同CPU、GPU型号的机器上。)
3.混合(alpha、擦出、重叠、硬光、加亮、和加暗模式)。
4.大于1024*1024的结构尺寸。
5.视频。
6.使用软键盘时调整视角以显示文本输入字段。
*特别注意:在IOS上的GPU渲染仅限于渲染位图、实心阴影以及其cacheBitmap属性设置为true的现实对象。
之后还有其他关于优化cpu和内存的使用注意事项,请关注我的如何降低应用程序对内存和CPU的消耗,提高程序运行效率(二)。