了解对象池
对象池的工作原理:
对象池的工作原理的核心有两点:使用和缓存,即对于那些被频繁使用的对象,在使用完后,不立即将它们释放,而是将它们缓存起来,以供后续的应用程序重复使用,从而减少创建对象和释放对象的次数,进而改善应用程序的性能。
优点:能快速取出对象节省了NEW对象所产生的cpu,时间的消耗。能很好的控制内存的占用,使用时从对象池取出,使用完毕放回。中间不涉及到对象销毁创建,所以内存占用是定量的。
缺点:对象池同样消耗new同样对象所消耗的时间,对象池从创建到结束消耗定量的内存。对象池只适合大量的对象需要被重复创建使用销毁创建使用销毁的情况。非提前初始化式内存池,缓存as值类型的对象如:Point反而产生更大的消耗。
在as3游戏开发中,内存问题基本是开发者最为头疼的了,官方也没具体的内存优化指导,开发者只能自己摸索着。显示列表的层级removechild、事件监听的及时移除或者弱引用。这些都是对于内存问题要注意的,因为AS3的垃圾回收机制并不是那么‘勤劳’的,垃圾回收只会在特定的时刻,或者是内存达到一定的瓶颈时才会进行。所以开发者要特别注意开发细节上的处理来节省内存。对象池是一个很好的方法。
比如在制作子弹射击的时候,子弹每次都被new出来。这样肯定很消耗内存。如果子弹new出来后屏幕上不需要这颗子弹了。可以将其放入对象池中。再次new的时候可以重复利用。
要实现一个对象池,一般会涉及到以下的几个类:
目标对象(SomeObject)类 该类就是程序中频繁使用的对象。
对象池(ObjectPool)类 该类主要用于管理对象的借出和归还,并通知对象池完成相应的工作。它至少包含两个方法:
package tools { import flash.utils.Dictionary; import flash.utils.getDefinitionByName; import flash.utils.getQualifiedClassName; /** * 用于显示对象的对象池类 */ public class ObjectPool { private static var instance:ObjectPool; /** * 作为对象池的词典dict */ private var objPoolDict:Dictionary=new Dictionary(); public function ObjectPool() { } public static function getInstance():ObjectPool { if (instance == null) { instance=new ObjectPool; } return instance; } /** * 向对象池中放入对象,以便重复利用 * @param disObj 要的放入对象 */ public function push(oldObj:Object):void { var objName:String=getQualifiedClassName(oldObj); if (oldObj == null) { return; } if (this.objPoolDict[objName] == null) { this.objPoolDict[objName]=[]; } this.objPoolDict[objName].push(oldObj); } /** * 从对象池中取出需要的对象 * @param targetObj 需要的对象类类名,没必要必须是类实例名 类名就可以 * @return 取出的相应对象 * */ public function pop(targetObj:Object):Object { var objName:String=getQualifiedClassName(targetObj); if (this.objPoolDict[objName] != null && this.objPoolDict[objName].length > 0) { return this.objPoolDict[objName].pop() as Object; } var objClass:Class=getDefinitionByName(objName) as Class; var obj:Object=new objClass as Object; return obj; } } }