合理使用内存(一)——Flash平台性能优化系列

节省内存对于应用程序是非常重要的,必须限制应用程序占用的内存量,来提高用户的

 

1、选择合适的显示对象

 

常用到的显示对象有:Shape、Sprite、MovieClip。各个显示对象的内存使用量测试如下:

 

trace(getSize(new Shape()));
//结果:248

trace(getSize(new Sprite()));
//结果:424

trace(getSize(new MovieClip()));
//结果:456

 

注:getSize()方法可以得到对象在内存中占用的字节数。

 

可以看出MovieClip比Shape的内存使用量大很多,使用不合理将会造成内存的浪费。对于这三个显示对象的使用原则是:对于非交互的简单形状,使用Shape对象;对于不需要时间轴的,但是需要交互的使用Sprite对象;对用使用时间轴的动画,使用MovieClip对象。

 

2、尽量重用对象

 

优化内存的另一个简单的方法是尽可能重复使用对象,避免重新创建对象。一下是一段创建平铺效果的代码,比较浪费内存:

 

var myImage:BitmapData;
var myContainer:Bitmap;
const MAX_NUM:int = 300;

for (var i:int = 0; i < MAX_NUM;++i) {
    myImage = new BitmapData(20, 20, false, 0xF0D062);

    myContainer = new Bitmap(myImage);
				
    addChild(myContainer);
				
    myContainer.x = (myContainer.width + 8) * Math.round(i % 20);
    myContainer.y = (myContainer.height + 8) * int(i / 20);
}

 

注:四舍五入使用Math.round()方法比较好。

 

优化后的版本仅仅创建了一个BitmapData示例:

 

var myImage:BitmapData = new BitmapData(20, 20,false,0xF0D062);
var myContainer:Bitmap;
const MAX_NUM:int = 300;
			
for (var i:int = 0; i < MAX_NUM;++i) {
    myContainer = new Bitmap(myImage);
				
    addChild(myContainer);
				
    myContainer.x = (myContainer.width + 8) * Math.round(i % 20);
    myContainer.y = (myContainer.height + 8) * int(i / 20);
}

 

优化后节省大大约700KB的内存,效果可观。

 

3、适当的时候使用对象池

 

涉及到不断重复使用对象的情形,可以考虑对象池。对象的原理是,在初始化应用程序期间创建一定数量的对象,存储到一个池中(例如Array或者Vector对象)。对一个对象完成操作后,释放掉该对象占用的CPU资源,然后删除所有相互的引用,将该对象放回到池中,在需要时可对其取出。

 

对象池可以减少示例化对象的操作,还可以减少垃圾回收期运行的机会,从而显著提高应用程序运行的速度。下面首先创建一个存放Sprite对象池作为示例:

 

package zhangqgc.util 
{
	import flash.display.Sprite;
	/**
	 * Sprite 对象池
	 * @author zhangqgc
	 */
	public final class SpritePool
	{
		
		private static var MAX_VALUE:uint;			//最大对象数
		private static var GROWTH_VALUE:uint;		//增长数量
		private static var counter:uint;			//对象池中剩余对象数
		private static var pool:Vector.<Sprite>;	        //对象池
		private static var currentSprite:Sprite;	        //当前对象
		
		//初始化对象池
		public static function initialize(maxPoolSize:uint, growthValue:uint):void {
			MAX_VALUE = maxPoolSize;
			GROWTH_VALUE = growthValue;
			counter = maxPoolSize;
			
			var i:uint = maxPoolSize;
			
			pool = new Vector.<Sprite>(MAX_VALUE);
			while (--i > -1) {
				pool[i] = new Sprite();
			}
		}
		
		//获取对象
		public static function getSprite():Sprite {
			if (counter > 0) {
				return currentSprite = pool[--counter];
			}
			
			//对象不够用的,按照初始化时提供的增长数据量增长
			var i:uint = GROWTH_VALUE;
			while (--i > -1) {
				pool.unshift(new Sprite());
			}
			counter = GROWTH_VALUE;
			return getSprite();
		}
		
		//销毁对象
		public static function disposeSprite(disposedSpriete:Sprite):void {
			pool[counter++] = disposedSpriete;
		}
		
	}

}

 

下面做个例子:开始从对象池中获取多个Sprite对象,在鼠标点击舞台时,将所有的对象回收。

 

package zhangqgc 
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	
	import zhangqgc.util.SpritePool;
	
	/**
	 * Sprite 对象池使用实例
	 * @author zhangqgc
	 */
	public class SpritePoolExample extends Sprite
	{
		
		
		public function SpritePoolExample() 
		{
			const MAX_SPRITES:uint = 100;
			const GROWTH_VALUE:uint = MAX_SPRITES >> 1;//开方
			const MAX_NUM:uint = 10;
			
			SpritePool.initialize(MAX_SPRITES, GROWTH_VALUE);
			
			var currentSprite:Sprite;
			var container:Sprite = SpritePool.getSprite();
			
			addChild(container);
			
			for (var i:int = 0; i < MAX_NUM; i++) {
				for (var j:int = 0; j < MAX_NUM; j++ ) {
					currentSprite = SpritePool.getSprite();    //获取对象
					currentSprite.graphics.beginFill(0x990000);
					currentSprite.graphics.drawCircle(10, 10, 10);
					currentSprite.x = j * (currentSprite.width +5);
					currentSprite.y = i * (currentSprite.width + 5);
					container.addChild(currentSprite);
				}
			}
			
			stage.addEventListener(MouseEvent.DOUBLE_CLICK, removeDots);
			
			function removeDots(e:MouseEvent):void {
				while (container.numChildren > 0) {
					SpritePool.disposeSprite(container.removeChildAt(0) as Sprite);    //回收对象
				}
			}
		}
		
	}

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值