对象池适用于:

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

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

public class ObjectPool<T> where T : class, new()
{
private Stack<T> m_objectStack = new Stack<T>(); public T New()
{
return (m_objectStack.Count == ) ? 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 > )
{
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>>(,
(list) => {
list.Clear();
},
(list) => {
//初始化容量为1024
list.Capacity = ;
}); 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 = ; 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 = ;
}
}

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

对象池 object pool的更多相关文章

  1. [译]Unity3D内存管理——对象池(Object Pool)

    原文地址:C# Memory Management for Unity Developers (part 3 of 3), 其实从原文标题可以看出,这是一系列文章中的第三篇,前两篇讲解了从C#语言本身 ...

  2. go语言学习--go的临时对象池--sync.Pool

    一个sync.Pool对象就是一组临时对象的集合.Pool是协程安全的. Pool用于存储那些被分配了但是没有被使用,而未来可能会使用的值,以减小垃圾回收的压力.一个比较好的例子是fmt包,fmt包总 ...

  3. go的临时对象池--sync.Pool

    作者:bigtom链接:https://www.jianshu.com/p/2bd41a8f2254來源:简书   一个sync.Pool对象就是一组临时对象的集合.Pool是协程安全的. Pool用 ...

  4. Golang 临时对象池 sync.Pool

    Go 1.3 的sync包中加入一个新特性:Pool.官方文档可以看这里http://golang.org/pkg/sync/#Pool 这个类设计的目的是用来保存和复用临时对象,以减少内存分配,降低 ...

  5. Phaser3 对象池随机产生炸弹并销毁

    效果图 对象池 Object Pool scene.js /// <reference path="../../libs/phaser/phaser.min.js"/> ...

  6. Unity性能优化-对象池

    1.对象池Object Pool的原理: 有些GameObject是在游戏中需要频繁生成并销毁的(比如射击游戏中的子弹),以前的常规做法是:Instantiate不断生成预设件Prefab,然后采用碰 ...

  7. Unity对象池的实现

    对象池是一个单例类: using System.Collections; using System.Collections.Generic; using UnityEngine; public cla ...

  8. Java对象池技术的原理及其实现

    看到一片有关于java 对象基础知识,故转载一下,同时学习一下. 摘 要 本文在分析对象池技术基本原理的基础上,给出了对象池技术的两种实现方式.还指出了使用对象池技术时所应注意的问题. 关键词 对象池 ...

  9. 【JVM】Java 8 中的常量池、字符串池、包装类对象池

    1 - 引言 2 - 常量池 2.1 你真的懂 Java的“字面量”和“常量”吗? 2.2 常量和静态/运行时常量池有什么关系?什么是常量池? 2.3 字节码下的常量池以及常量池的加载机制 2.4 是 ...

随机推荐

  1. Java-Runoob-高级教程-实例-数组:04. Java 实例 – 数组反转

    ylbtech-Java-Runoob-高级教程-实例-数组:04. Java 实例 – 数组反转 1.返回顶部 1. Java 实例 - 数组反转  Java 实例 以下实例中我们使用 Collec ...

  2. [转]CSKIN 作者分享的图片处理类

    本代码来自:http://bbs.cskin.net/forum.php?mod=viewthread&tid=113&fromuid=2446 里面没有我想找的任意角度旋转的方法,代 ...

  3. 除了用作缓存数据,Redis还可以做这些

    Redis应该说是目前最受欢迎的NoSQL数据库之一了.Redis通常被作为缓存组件,用作缓存数据.不过,除了可以缓存数据,其实Redis可以做的事还有很多.下面列举几例,供大家参考. 1.最新列表 ...

  4. [UE4]通过代码改变材质

    OrangeMaterial = ConstructorStatics.OrangeMaterial.Get(); , OrangeMaterial); 使用到的结构体如下: struct FCons ...

  5. GSO/TSO/GRO等对VirtIO虚机的网络性能影响分析(by quqi99)

    作者:张华  发表于:2016-04-05版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) IP层 ...

  6. webpack(2)--Entry

    Entry entry是配置模块的入口,可以抽象成输入,webpack执行构建的第一步将从入口开始搜寻及递归解析出所有入口依赖的模块. 注意: entry是必填,若不填写则将导致webpack报错退出 ...

  7. tcp 大文件上传 ,切换目录 及登陆文件加盐处理

    实现大文件的传输 服务器 import socketimport jsonimport structsk = socket.socket()sk.bind(("127.0.0.1" ...

  8. c++官方文档-枚举-联合体-结构体-typedef-using

    #include<iostream> #include <new> #include<stdio.h> using namespace std; /** * url ...

  9. PHP过滤各种HTML标签的表达式,值得收藏

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  10. MYSQL三大范式

    第一范式:确保每列的原子性. 第一范式是最基本的范式. 数据库表中的字段都是单一属性的,不可再分. 只要是关系数据库都满足第一范式 如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子 ...