现在的位置: 首页 > 综合 > 正文

Flash Player垃圾回收机制强制执行

2013年11月14日 ⁄ 综合 ⁄ 共 1977字 ⁄ 字号 评论关闭

AVM2理论上是自带垃圾回收机的,但是具体何时进行垃圾回收,理论上非人为所能控制,而我们若要强制启用垃圾回收机,则需要用一些非正规手段,比如如下会提到的手段。

所谓强制执行垃圾回收机,是指通过故意使swf在运行时出错,然后throw出错误,而同时通过catch error来继续运行swf文件。而垃圾回收机则会在swf抛出错误的时候,被强制执行一次,以清除内存中无效的数据占用,减少资源的消耗。

try{
        new LocalConnection().connect("MoonSpirit");
        new LocalConnection().connect("MoonSpirit");
}catch(error : Error){}运行上述代码,可强制执行一次垃圾回收机。具体测试:
分别用initNoBitmapDataView()和initBitmapDataView()进行10k个举行元素创建
测试结果:
1.1不使用BitmapData 内存占用 40M
2.1使用BitmapData 依旧内存占用 40M!
原因分析: 虽然_sqrList被设为null,但是原先被_sqrList所引用的1w个sprite数据依旧在内存中存在,虽然AMV2自带垃圾回收机,但是何时进行垃圾回收是不确定的。而要强制执行垃圾回收机,则要用上文提到的hack手段
2.2使用BitmapData + 垃圾回收hack 内存占用 12M

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.net.LocalConnection;
	
	public class MoonSpirit extends Sprite
	{
		
		private const SQR_AMOUNT  : int = 10000;   //方块数量
		private var _container_sp : Sprite;        //容器sprite
		private var _sqrList      : Array;         //所有方块的引用
		
		public function MoonSpirit()
		{
			init();
		}
		
		private function init() : void{
			_container_sp = new Sprite();
			addChild(_container_sp);
//			initNoBitmapDataView( );
			initBitmapDataView();
		}
		//初始化 通过通常手段 显示
		private function initNoBitmapDataView() : void {
			layoutTenThousandSqr();
		}
		//初始化 通过BitmapData快照 显示
		private function initBitmapDataView() : void {
			layoutTenThousandSqr();
			var myBitmapDataObject : BitmapData = new BitmapData(150, 150, false, 0xFF0000);
			var myImage:Bitmap = new Bitmap(myBitmapDataObject);
			addChild(myImage);
			unLayoutTenThousandSqr();
			_sqrList = null;
			doClearance();
		}
		private function layoutTenThousandSqr() : void {
			_sqrList = new Array();
			for(var i : int = 0; i < SQR_AMOUNT; i++){
				_sqrList.push(new Sprite());
				_sqrList[i].graphics.beginFill(0xff0000);
				_sqrList[i].graphics.drawRect(0,0,100,100);
				_sqrList[i].graphics.endFill();
				_container_sp.addChild(_sqrList[i]);
			}
		}
		//不显示
		private function unLayoutTenThousandSqr() : void {
			for(var i : int = 0; i < SQR_AMOUNT; i++){
				_container_sp.removeChild(_sqrList[i]);
				delete _sqrList[i];
			}
		}
		//精髓,垃圾回收机强制调用
		private function doClearance( ) : void {
			trace("clear");
			try{
				new LocalConnection().connect("foo");
				new LocalConnection().connect("foo");
			}catch(error : Error){
			}
		}
	}
}

抱歉!评论已关闭.