• (转)flash对象池技术


     
     
    请尽可能使用对象池。

    另一个重要优化称为对象池,涉及到不断重复使用对象。在初始化应用程序期间创建一定数量的对象并将其存储在一个池中,例如 Array 或 Vector 对象。对一个对象完成操作后,停用该对象以免它占用 CPU 资源,然后删除所有相互引用。然而,不要将引用设置为null,这将使它符合垃圾回收条件。只需将该对象放回到池中,在需要新对象时可以对其进行检索。

    重用对象可减少实例化对象的需求,而实例化对象成本很高。还可以减少垃圾回收器运行的机会,从而提高应用程序运行速度。以下代码演示对象池技术:

    package 
    { 
        import flash.display.Sprite; 
         
        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(disposedSprite:Sprite):void 
            { 
                pool[counter++] = disposedSprite; 
            } 
        } 
    }

    SpritePool 类在初始化应用程序时创建新的对象池。getSprite()方法返回这些对象的实例,而disposeSprite()方法释放这些实例。代码允许池容量用尽时可以增长。还可以创建固定大小的池,这样当池容量用尽时将不会分配新对象。尽可能避免在循环中创建新对象。有关详细信息,请参见释放内存。以下代码使用 SpritePool 类检索新实例:

    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.CLICK, removeDots ); 
      
    function removeDots ( e:MouseEvent ):void 
    { 
        while (container.numChildren > 0 ) 
            SpritePool.disposeSprite (container.removeChildAt(0) as Sprite ); 
    }
    注: 池矢量始终引用 Sprite 对象。如果要从内存中完全删除对象,需要对 SpritePool 类使用dispose()方法,从而删除所有剩余引用。
    ============================================================================================
    (最近比较忙,就提前把半成品放出来了~有什么改进或问题,请跟帖~以后有其他成果再拿出来分享~)
    对象池
    基本功能描述:把同类对象临时保存,可以随时取出使用;在内存紧张,垃圾回收机启动时,池内

    对象被自动回收清空。

    原理和性能:原理:AS3弱引用的应用,性能:垃圾回收机制自动处理,无需额外监控函数,添加此

    类无需额外开销。

    用途:用于新建需要巨大开销,但又不能肯定必须长期进驻的对象。例如:游戏里的场景,玩家可

    能不断的跳转场景,这时有两种模式:1.玩家进入过的场景都保存起来,(缺点,游戏内存随着

    进入场景增加剧增);2.玩家进入别的场景后删除原场景,(缺点,如果玩家不断的在2个场景切

    换,就每次都要重新加载场景,造成时间的浪费和场景初始化的开销)。
    对象池的解决方案:用户一旦删除场景,并不立刻删除,而是放进对象池,当他再次进入此场景

    ,则从对象池里取出,而不需要重新加载;但是,如果用户出入大量场景,使到内存剧增,触发

    了垃圾回收机,则内存池会被自动清空,使内存回到合理幅度。这时,用户重新进入场景重新加

    载过程也理所当然了。可以做到性能与体验的平衡。
    同时,可用于飞机子弹等领域,当然,需要权衡利弊,此池并适合任何项目。相反,很多项目是

    不适合的。

    注意事项:
    1.op.push(obj)后,请确保把obj的外部所有强引用删除。
    2.如果发现gc()后op.length不是空的,请检查gc()函数是否实现功能,同时检查push进对象池的

    对象外部强引用是否完全删除。
    3.测试时,可以使用gc()来测试性能,但在项目发布后gc()函数应该废弃。Adobe已经强调gc()函

    数会破坏cpu的负载性能,建议AS编程人员在正规作品里不要使用gc();
    4.一个对象池应该只保存一种对象,因为op.pop():Object函数不能保证取给你的是哪个对象。

    扩展:大家看到ObjectPool.as后是否吓到~代码这么少也叫类~o(∩_∩)o 哈哈
    其实就是考虑到对象池的扩展性,现在对象池有个缺点。就是传入和传出类型都是Object类,当

    然不能符合各种需求,这就需要写子类派生他...所以我尽量吧父类写得简单,只实现最基本的功

    能,后面就靠各位去扩展了。

    扩展方向:
    1.给对象池加大小,只有当内存涨到一定幅度,才给对象池解锁,让它可以被回收。
    2.通用对象池,可以保存不同类型的对象。
    3.其他你想到的扩展方式。

    稍候上传附件

    ObjectPool.rar

     

    自:http://bbs.9ria.com/thread-41434-1-1.html

  • 相关阅读:
    .Net 集合类
    Linux与Windows共享资源samba+mount
    Linux系统基本设置
    python实例31[urllib.request.urlopen获取股票信息]
    iptables 基本命令使用举例
    API控制VM虚拟机(VM Workstation or VM Server)
    vbs实现unicode和ascii的转化
    python语法31[string的print和format]
    Windows下运行XServer
    Perl IDE之Perl Express和Eclipse+EPIC+PadWalker
  • 原文地址:https://www.cnblogs.com/wonderKK/p/2888741.html
Copyright © 2020-2023  润新知