as3 性能之对象池技术

优化 Adobe® Flash® Platform 的性能:http://help.adobe.com/zh_CN/as3/mobile/index.html

为什么使用对象池?

因为FLASH是托管的GC清理资源,具体什么时候清理只有GC知道,那么我们的游戏的性能就.........

例如:游戏里点击按钮会加载一张图片,再次点击图片,会销毁图片。

那么如果用户不停的点击,会执行不断的加载 显示 销毁。内存就会很难控制。

摘自Adobe的一段

http://help.adobe.com/zh_CN/as3/mobile/WS948100b6829bd5a6-19cd3c2412513c24bce-8000.html

请尽可能使用对象池。

另一个重要优化称为对象池,涉及到不断重复使用对象。在初始化应用程序期间创建一定数量的对象并将其存储在一个池中,

例如 Array 或 Vector 对象。对一个对象完成操作后,停用该对象以免它占用 CPU 资源,然后删除所有相互引用。然而,

不要将引用设置为null,这将使它符合垃圾回收条件。只需将该对象放回到池中,在需要新对象时可以对其进行检索。

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

使用了对象池后

我们会首先创建出需要的实例,并且把它扔进对象池objectPool

    • 对象池应该是靠单例获取
    • 开始时:初始化的时候直接给池子一定量的对象
    • 使用时:从objectPool里borrow一个
    • 归还时(释放):return它到objectPool中去
    • 完全释放:池矢量始终引用 Sprite 对象。如果要从内存中完全删除对象,需要对 SpritePool 类使用dispose()方法,从而删除所有剩余引用。
    • 所有的打算放到对象池的对象(显示对象 or 音频对象 等等)都需要继承自IPool接口
    • IPool 接口需要实现:reset() dispose()
      reset():重置对象的 这个很有必要的。当很多显示对象当return时候 都要被重置
             重置需要做的:对已经填充的数据恢复默认,对动画状态回到默认状态。总之就是让其回到刚刚构造完时的样子
      dispose():该接口主要是在彻底销毁对象池时 需要把对象池里的元素都销毁,每个元素可能会在dispose里执行以下
                 removeEventListener
                 BitmapData.dispose();
                 delete object
                 stopMovieOrSound

1:IPoolItem.as 接口类

package com.naiking.interfaces
{
    /**
     * @author 醒着☆☆
     */
    public interface IPoolItem
    {
        function reset():void;
        function dispose():void;
    }
}

2:ObjectPoolManager.as对象池管理类

package com.naiking.manager
{
    import com.naiking.data.HashMap;
    import com.naiking.interfaces.IPoolItem;

    import flash.utils.getDefinitionByName;

    /**
     * ObjectPoolManager
     * @醒着☆☆
     *
     */
    public class ObjectPoolManager
    {
        //dictionary
        private var pools:HashMap=new HashMap();
        /**
         * @param classType:ClassName String
         * @param maxSize
         */
        public function initPool(classType:String,maxSize:int):void
        {
            //create all item by once
            trace("Created pool of "+classType);
            if(pools.containsKey(classType))
                return;
            var itemAry:Array=[];
            pools.add(classType,itemAry);
            var cls:Class=getDefinitionByName(classType) as Class;
            for(var i:int=0;i<maxSize;i++)
            {
                itemAry.push(new cls());
            }
        }
        public function returnItem(classType:String,item:IPoolItem):void
        {
            if(!pools.containsKey(classType))
            {
                throw new Error("Not find:"+classType+" pool");
                return;
            }
            trace("Give back item:"+classType);
            item.reset();
            (pools.getValue(classType) as Array).push(item);
        }
        /**
         *Get one item from pool
         * @param classType:
         * @return
         *
         */
        public function borrowItem(classType:String):IPoolItem
        {
            if(!pools.containsKey(classType))
            {
                throw new Error("Not find:"+classType+" pool");
                return;
            }
            if((pools.getValue(classType) as Array).length==0)
            {
                throw new Error("The Pool:"+classType+" is full,Need expand");
                return;
            }
            trace("Borrowed a item of"+classType);
            return (pools.getValue(classType) as Array).pop();
        }
        public function disposePool(classType:String):void
        {
            if(!pools.containsKey(classType))
                return;
            //clear pool
            var itemAry:Array=pools.getValue(classType) as Array;
            //dispose objects in pool
            for(var i:int=0;i<itemAry.length;i++)
            {
                /*
                the dispose() function is used to
                removeEventListener、dispose Bitmapdata、delete dynamic property
                */
                (itemAry[i] as IPoolItem).dispose();
            }
            itemAry=null;
            //remove this key from dictionary
            pools.remove(classType);
        }
        public function ObjectPoolManager(_sig:Sig)
        {
        }
        private  static var _instance:ObjectPoolManager;
        public static function getInstance():ObjectPoolManager
        {
            if(!_instance)
                _instance=new ObjectPoolManager(new Sig());
            return _instance;
        }
    }
}
final class Sig{}

3:HashMap.as 基本哈希表

package com.naiking.data
{
  import flash.utils.Dictionary;
  /**
   * 哈希图
   * @author 醒着☆☆
   *
   */
  public class HashMap
  {
      private var _length:int;
      private var _content:Dictionary;
      private var _weakKeys:Boolean;

      /**
       * 构造函数
       * @param weakKeys 是否是弱引用
       *
       */
      public function HashMap(weakKeys:Boolean = false)
      {
          _weakKeys = weakKeys;
          _length = 0;
          _content = new Dictionary(weakKeys);
      }

      /**
       * 当前HashMap的长度
       * @return
       *
       */
      public function get length():int
      {
          return _length;
      }

      /**
       * 当前HashMap是否为空
       * @return
       *
       */
      public function isEmpty():Boolean
      {
          return _length == 0;
      }

      /**
       * 获取Key列表
       * @return
       *
       */
      public function getKeys():Array
      {
          var temp:Array = new Array(_length);
          var index:int = 0;
          var i:*;
          for(i in _content)
          {
              temp[index] = i;
              index++;
          }
          return temp;
      }

      /**
       * 获取Value列表
       * @return
       *
       */
      public function getValues():Array
      {
          var temp:Array = new Array(_length);
          var index:int = 0;
          var i:*;
          for each(i in _content)
          {
              temp[index] = i;
              index++;
          }
          return temp;
      }

      /**
       * 对Key列表中的每一项执行函数
       * @param func
       *
       */
      public function eachKey(func:Function):void
      {
          var i:*;
          for(i in _content)
          {
              func(i);
          }
      }

      /**
       * 对Value列表中的每一项执行函数
       * @param func
       *
       */
      public function eachValue(func:Function):void
      {
          var i:*;
          for each(i in _content)
          {
              func(i);
          }
      }

      /**
       * 对整个HashMap的每一项执行函数
       * @param func 第一个参数是key,第二个参数是Value
       *
       */
      public function each2(func:Function):void
      {
          var i:*;
          for(i in _content)
          {
              func(i,_content[i]);
          }
      }

      /**
       * 当前HashMap是否有value
       * @param value
       * @return
       *
       */
      public function containsValue(value:*):Boolean
      {
          var i:*;
          for each(i in _content)
          {
              if (i === value)
              {
                  return true;
              }
          }
          return false;
      }

      /**
       * 对HashMap中的每一项执行测试函数,直到获得返回 true 的项。
       * @param func 第一个参数是key,第二个参数是Value
       * @return
       *
       */
      public function some(func:Function):Boolean
      {
          var i:*;
          for(i in _content)
          {
              if(func(i,_content[i]))
              {
                  return true;
              }
          }
          return false;
      }

      /**
       * 对HashMap中的每一项执行测试函数,并构造一个新数组(值,不包含Key),其中的所有项都对指定的函数返回 true。 如果某项返回 false,则新数组中将不包含此项。
       * @param func 第一个参数是key,第二个参数是Value
       * @return
       *
       */
      public function filter(func:Function):Array
      {
          var arr:Array = [];
          var i:*;
          var v:*;
          for(i in _content)
          {
              v = _content[i];
              if(func(i,v))
              {
                  arr.push(v);
              }
          }
          return arr;
      }

      /**
       * 当前HashMap是否有Key
       * @param key
       * @return
       *
       */
      public function containsKey(key:*):Boolean
      {
          if (_content[key] === undefined)
          {
              return false;
          }
          return true;
      }

      /**
       * 从指定的Key中获取 Value
       * @param key
       * @return
       *
       */
      public function getValue(key:*):*
      {
          var value:* = _content[key];
          return value === undefined ? null : value;
      }

      /**
       * 从指定的Value中获取Key
       * @param value
       * @return
       *
       */
      public function getKey(value:*):*
      {
          var i:*;
          for(i in _content)
          {
              if(_content[i] == value)
              {
                  return i;
              }
          }
          return null;
      }

      /**
       * 添加key value,返回的是旧的key对应的value,如果没有则返回null
       * @param key
       * @param value
       * @return
       *
       */
      public function add(key:*, value:*):*
      {
          if (key == null)
          {
              throw new ArgumentError("cannot put a value with undefined or null key!");
              return null;
          }
          if(value === undefined)
          {
              return null;
          }
          else
          {
              if (_content[key] === undefined)
              {
                  _length++;
              }
              var oldValue:* = getValue(key);
              _content[key] = value;
              return oldValue;
          }
      }

      /**
       * 移除key value,返回的是旧的key对应的value,如果没有则返回null
       * @param key
       * @return
       *
       */
      public function remove(key:*):*
      {
          if (_content[key] === undefined)
          {
              return null;
          }
          var temp:* = _content[key];
          delete _content[key];
          _length--;
          return temp;
      }

      /**
       * 清空当前HashMap
       *
       */
      public function clear():void
      {
          _length = 0;
          _content = new Dictionary(_weakKeys);
      }

      /**
       * 克隆当前 HashMap
       * @return
       *
       */
      public function clone():HashMap
      {
          var temp:HashMap = new HashMap(_weakKeys);
          var i:*;
          for(i in _content)
          {
              temp.add(i, _content[i]);
          }
          return temp;
      }

      public function toString():String
      {
          var ks:Array = getKeys();
          var vs:Array = getValues();
          var len:int = ks.length;
          var temp:String = "HashMap Content:\n";
          var i:int;
          for(i = 0; i < len; i++)
          {
              temp += ks[i] + " -> " + vs[i] + "\n";
          }
          return temp;
      }
  }

}
时间: 2024-10-12 14:31:46

as3 性能之对象池技术的相关文章

探索对象池技术

对象池技术是一种常见的对象缓存手段.’对象’意味着池中的内容是一种结构化实体,这也就是一般意义上面向对象中的对象模型:’池’(或动词池化)意味着将有生命周期的对象缓存到’池子’中进行管理,即用即取.缓存的目的大多是为了提升性能,对象池技术的目的也即如此.所以,对象池技术的本质简单来说就是:将具有生命周期的结构化对象缓存到带有一定管理功能的容器中,以提高对象的访问性能. 处理网络连接是对象池使用最多的场景.比如一些RPC框架的NettyChannel缓存(如motan),以及数据库连接池的Conn

对象池技术

在arpg页游场景里面,经常被杀的怪物对象需要反复生成.销毁.频繁的触发垃圾回收会降低游戏运行效率,对象池技术就是为了解决这种问题 对象池特点: 1.聚合有一个容器,该容器装有已生成的对象: 2.封装对象的生成操作: 3.封装对象的销毁操作: ============================================================ ==============简单的示例,可以自动扩容的对象池=========================== public cl

unity3D初识对象池技术

对象池概念:用来优化游戏,提升游戏性能,如飞机大战 ,当触及到大量的物体需要不断的重新的被创建的时候,这个时候就适合用到对象池. 下面我会写一个例子更详细的来说明下这个对象池的用法: 对象池主要有2个方法 1:从池里去找东西 2:往池里放东西 这里我是写了一个打砖块的例子,后续我会把整个游戏的代码分享出来,里面包含一个拿和一个放的方法. using UnityEngine; using System.Collections; using System.Collections.Generic; /

屏幕坐标和世界坐标的转换+对象池技术(3D打地鼠小游戏)

游戏中可能经常会遇到需要某个物体跟着鼠标移动,然后又需要把物体放在某个鼠标指定的位置 实现方式 Camera.main.WorldToScreenPoint Camera.main.ScreenToWorldPoint 3D打地鼠实例 我这里用到的素材都比较简陋,几乎全是用Unity做的 首先是锤子 就是两个Cylinder,在把手的位置放一个空物体用于模拟锤子的动作,命名为Hammer,把锤子作为Hammer的子物体,给Hammer添加Animation动画: 在三个关键帧位置设置Hammer

大数据技术之_27_电商平台数据分析项目_02_预备知识 + Scala + Spark Core + Spark SQL + Spark Streaming + Java 对象池

第0章 预备知识0.1 Scala0.1.1 Scala 操作符0.1.2 拉链操作0.2 Spark Core0.2.1 Spark RDD 持久化0.2.2 Spark 共享变量0.3 Spark SQL0.3.1 RDD.DataFrame 与 DataSet0.3.2 DataSet 与 RDD 互操作0.3.3 RDD.DataFrame 与 DataSet 之间的转换0.3.4 用户自定义聚合函数(UDAF)0.3.5 开窗函数0.4 Spark Streaming0.4.1 Dst

对象池实现分析

对象池实现分析 什么是对象池技术?对象池应用在哪些地方? 对象池其实就是缓存一些对象从而避免大量创建同一个类型的对象,类似线程池的概念.对象池缓存了一些已经创建好的对象,避免需要时才创建对象,同时限制了实例的个数.池化技术最终要的就是重复的使用池内已经创建的对象.从上面的内容就可以看出对象池适用于以下几个场景: 创建对象的开销大 会创建大量的实例 限制一些资源的使用 如果创建一个对象的开销特别大,那么提前创建一些可以使用的并且缓存起来(池化技术就是重复使用对象,提前创建并缓存起来重复使用就是池化

Netty轻量级对象池实现分析

什么是对象池技术?对象池应用在哪些地方? 对象池其实就是缓存一些对象从而避免大量创建同一个类型的对象,类似线程池的概念.对象池缓存了一些已经创建好的对象,避免需要时才创建对象,同时限制了实例的个数.池化技术最终要的就是重复的使用池内已经创建的对象.从上面的内容就可以看出对象池适用于以下几个场景: 创建对象的开销大 会创建大量的实例 限制一些资源的使用 如果创建一个对象的开销特别大,那么提前创建一些可以使用的并且缓存起来(池化技术就是重复使用对象,提前创建并缓存起来重复使用就是池化)可以降低创建对

Unity3D 基于预设(Prefab)的泛型对象池实现

背景 在研究Inventory Pro插件的时候,发现老外实现的一个泛型对象池,觉得设计的小巧实用,不敢私藏,特此共享出来. 以前也看过很多博友关于对象池的总结分享,但是世界这么大,这么复杂到底什么样的对象池才是好的呢,我们发现通用的对象池未必适应所有的环境,比如基于UI的局部(从某个Scene,到某个Dialog)对象池,范围不同,需要的对象池就有不同的要求.本文就是介绍一种基于预设(Prefab)的局部UI对象池. 通用信息提示窗口的实现http://www.manew.com/thread

java/android 设计模式学习笔记(5)---对象池模式

这次要介绍一下对象池模式(Object Pool Pattern),这个模式为常见 23 种设计模式之外的设计模式,介绍的初衷主要是在平时的 android 开发中经常会看到,比如 ThreadPool 和 MessagePool 等. 在 java 中,所有对象的内存由虚拟机管理,所以在某些情况下,需要频繁创建一些生命周期很短使用完之后就可以立即销毁,但是数量很大的对象集合,那么此时 GC 的次数必然会增加,这时候为了减小系统 GC 的压力,对象池模式就很适用了.对象池模式也是创建型模式之一,