引用池(Reference Pool)

Why Pooling

在管理大量的对象时,有时此对象可能创建和初始化(比如Unity的ParticleSystem)或销毁需要大量时间。

为了这种避免频繁的对象创建和销毁,可以声明一个缓存,对象如果需要回收,可以暂时隐藏塞入这个缓存里来替代销毁,而需要新对象的时候,可以从缓存中直接拿取现有的对象,减少频繁创建和销毁对象带来的成本,实现对象的缓存和复用。

这种结构一般适用于创建对象的成本比较大并且创建比较频繁的情况,比如:

1.Unity的ParticleSystem在创建时Awake和Start阶段开销比较大,并且一般粒子是需要频繁调用的,这时就需要引用池去管理ParticleSystem。

2.线程的创建代价比较大,于是就有了常用的线程池。

引用池上限

引用池的上限是为了防止引用池过大,当一个引用类型被添加到引用池时,如果此引用池已满,则会直接销毁。

引用池接口

https://github.com/VMware233/VMFramework/blob/main/Assets/VMFramework/Main/Core/Collections/Pools/Pool/IPool.cs

可检查的引用池接口在继承了引用池接口的基础上,还有如下:

https://github.com/VMware233/VMFramework/blob/main/Assets/VMFramework/Main/Core/Collections/Pools/Pool/ICheckablePool.cs

内置的引用池实现

框架已经内置了一些引用池的具体实现。

DefaultPool

默认的引用池实现,注意此实现是非线程安全的。

实例化DefaultPool需要提供一个IPoolPolicy来提供Callback。

DefaultConcurrentPool

默认的引用池实现,与DefaultPool不同的是,此引用池的实现是线程安全的。

与DefaultPool一样,实例化需要一个IPoolPolicy。

IPoolPolicy

用来给默认的引用池实现提供Callback。

接口如下:

https://github.com/VMware233/VMFramework/blob/main/Assets/VMFramework/Main/Core/Collections/Pools/PoolPolicy/IPoolPolicy.cs

这四个Callback分别为:

  1. Create:引用池的缓存为空需要创建一个对象时

  2. PreGet:从池中的缓存获取一个对象时

  3. Return:归还给引用池一个对象时

  4. Clear:当引用池已满或者手动调用引用池的Clear函数时

默认的IPoolPolicy为:

https://github.com/VMware233/VMFramework/blob/main/Assets/VMFramework/Main/Core/Collections/Pools/PoolPolicy/DefaultPoolPolicy.cs

如果你觉得这些Callback很冗余,不需要这些Callback,那么为什么不直接使用Stack、Queue这些C#原生结构作为引用池?

引用池工具函数

https://github.com/VMware233/VMFramework/blob/main/Assets/VMFramework/Main/Core/Collections/Pools/Utility/PoolUtility.cs

最后更新于

这有帮助吗?