zoukankan      html  css  js  c++  java
  • 对象池 object pool

    对象池适用于:

    • 对象的创建很耗时
    • 对象频繁地释放再创建

    对象池的实现:将释放的对象放进对象池中,在新建对象时,从对象池取对象

    public class ObjectPool<T> where T : class, new()
    {
        private Stack<T> m_objectStack = new Stack<T>();
    
        public T New()
        {
            return (m_objectStack.Count == 0) ? new T() : m_objectStack.Pop();
        }
    
        public void Store(T t)
        {
            m_objectStack.Push(t);
        }
    }

    改进第一步:对象被重新使用前,reset所有的成员变量。

    public class ObjectPool<T> where T : class, new()
    {
        private Stack<T> m_objectStack;
    
        private Action<T> m_resetAction; //indicate whether need reset
        private Action<T> m_onetimeInitAction; //indicate whether need initialize
    
        public ObjectPool(int initialBufferSize, Action<T>
            ResetAction = null, Action<T> OnetimeInitAction = null)
        {
            m_objectStack = new Stack<T>(initialBufferSize);
            m_resetAction = ResetAction;
            m_onetimeInitAction = OnetimeInitAction;
        }
    
        public T New()
        {
            if (m_objectStack.Count > 0)
            {
                T t = m_objectStack.Pop();
    
                if (m_resetAction != null)
                    m_resetAction(t);
    
                return t;
            }
            else
            {
                T t = new T();
    
                if (m_onetimeInitAction != null)
                    m_onetimeInitAction(t);
    
                return t;
            }
        }
    
        public void Store(T obj)
        {
            m_objectStack.Push(obj);
        }
    }

    参数T被指明为”where T:class,new()”,意味着有两个限制。首先,T必须为一个类(毕竟,只有引用类型需要被obejct-pool);其次,它必须要有一个无参构造函数。

    以下是池的使用方法:

    class SomeClass : MonoBehaviour
    {
        private ObjectPool<List<Vector3>> m_poolOfListOfVector3 =
            //32为假设的最大数量
            new ObjectPool<List<Vector3>>(32,
            (list) => {
                list.Clear();
            },
            (list) => {
                //初始化容量为1024
                list.Capacity = 1024;
            });
    
        void Update()
        {
            List<Vector3> listVector3 = m_poolOfListOfVector3.New();
    
            // do stuff
    
            m_poolOfListOfVector3.Store(listVector3);
        }
    }

    改进第二步:允许一次性回收所有已经池化的对象

    public class ObjectPoolWithCollectiveReset<T> where T : class, new()
    {
        private List<T> m_objectList; //Stack<T>被List<T>代替,可以跟踪最近创建或释放的对象在list中索引
        private int m_nextAvailableIndex = 0;
    
        private Action<T> m_resetAction;
        private Action<T> m_onetimeInitAction;
    
        public ObjectPoolWithCollectiveReset(int initialBufferSize, Action<T>
            ResetAction = null, Action<T> OnetimeInitAction = null)
        {
            m_objectList = new List<T>(initialBufferSize);
            m_resetAction = ResetAction;
            m_onetimeInitAction = OnetimeInitAction;
        }
    
        public T New()
        {
            if (m_nextAvailableIndex < m_objectList.Count)
            {
                // an allocated object is already available; just reset it
                T t = m_objectList[m_nextAvailableIndex];
                m_nextAvailableIndex++;
    
                if (m_resetAction != null)
                    m_resetAction(t);
    
                return t;
            }
            else
            {
                // no allocated object is available
                T t = new T();
                m_objectList.Add(t);
                m_nextAvailableIndex++;
    
                if (m_onetimeInitAction != null)
                    m_onetimeInitAction(t);
    
                return t;
            }
        }
    
        public void ResetAll() //原本的store()
        {
           //重置索引
            m_nextAvailableIndex = 0;
        }
    }

    局限:显然,当我们需要一个其它类型的对象池时就需要重新申明一个。或许我们可以实现一个对用户透明。创建管理所有类型池的ObjectPool。

  • 相关阅读:
    Rust started
    修改cargo镜像源
    如何激发团队潜能?
    JVM 09.5 运行时数据区 堆 堆时对象分配的唯一选择吗 逃逸分析
    JVM 09.5 运行时数据区 堆 相关参数设置总结
    JVM 09.4 运行时数据区 堆 线程独占区域 TLAB
    JVM 09.3 运行时数据区 堆 调优/垃圾回收/小结
    JVM 09.2 运行时数据区 堆 年轻带/老年代/对象分配过程
    JVM 09.1 运行时数据区 堆 核心概述
    JVM 08 运行时数据区 本地方法栈
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/5015166.html
Copyright © 2011-2022 走看看