From 023ba44f57bcaec133c9200ca4a21a109209d890 Mon Sep 17 00:00:00 2001
From: GeWuYou <95328647+GeWuYou@users.noreply.github.com>
Date: Mon, 12 Jan 2026 14:44:19 +0800
Subject: [PATCH] =?UTF-8?q?docs(pool):=20=E5=AE=8C=E5=96=84=E5=AF=B9?=
=?UTF-8?q?=E8=B1=A1=E6=B1=A0=E7=B3=BB=E7=BB=9F=E6=96=87=E6=A1=A3=E5=B9=B6?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BD=BF=E7=94=A8=E7=A4=BA=E4=BE=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
更新 GFramework.Core 对象池系统的 README 文档,增加详细的功能说明、API
参考、使用示例和最佳实践。
主要变更包括:
- 补充核心组件的详细说明和代码示例
- 添加 IPoolableObject 接口的完整定义
- 添加 IObjectPoolSystem 接口和 AbstractObjectPoolSystem 抽象类的
详细说明
- 增加基本使用指南,包含池化对象定义和系统实现步骤
- 添加高级用法示例,如多键对象池管理和大小限制
- 补充游戏对象池、UI元素池等具体应用场景
- 添加性能优化建议和最佳实践指导
- 完善注意事项和相关包引用信息
---
GFramework.Core/pool/README.md | 942 ++++++++++++++++++++++++++++++++-
1 file changed, 919 insertions(+), 23 deletions(-)
diff --git a/GFramework.Core/pool/README.md b/GFramework.Core/pool/README.md
index 2e5527e..7ea5147 100644
--- a/GFramework.Core/pool/README.md
+++ b/GFramework.Core/pool/README.md
@@ -4,49 +4,945 @@
GFramework 的对象池系统是一个高效的内存管理机制,旨在减少垃圾回收(GC)压力,通过复用对象实例来提高应用程序性能。该系统实现了对象的创建、获取、释放和销毁的完整生命周期管理。
+**核心优势:**
+
+- **减少 GC 压力**:复用对象实例,避免频繁的内存分配和回收
+- **提高性能**:避免重复创建开销大的对象
+- **灵活管理**:支持多个独立的对象池,按需分类管理
+- **自动生命周期**:与 System 生命周期集成,自动管理对象销毁
+- **类型安全**:基于泛型实现,编译时类型检查
+
## 核心组件
### IPoolableObject 接口
-定义了可池化对象的行为规范,所有池化对象都需要实现此接口:
+定义了可池化对象的行为规范,所有需要池化的对象都必须实现此接口。
-- `OnAcquire()`: 当对象从池中获取时调用,用于初始化或重置对象状态
-- `OnRelease()`: 当对象被放回池中时调用,用于清理对象状态
-- `OnPoolDestroy()`: 当对象池被销毁时调用,用于执行最终清理
+```csharp
+public interface IPoolableObject
+{
+ ///
+ /// 当对象从池中获取时调用,用于初始化或重置对象状态
+ ///
+ void OnAcquire();
+
+ ///
+ /// 当对象被放回池中时调用,用于清理对象状态
+ ///
+ void OnRelease();
+
+ ///
+ /// 当对象池被销毁时调用,用于执行最终清理
+ ///
+ void OnPoolDestroy();
+}
+```
+
+**生命周期:**
+
+```
+创建 → Acquire(从池取出)→ 使用 → Release(放回池)→ 可再次 Acquire
+ ↓
+ Pool Destroy → OnPoolDestroy → 销毁
+```
### IObjectPoolSystem 接口
-定义了对象池系统的基本操作:
+定义了对象池系统的基本操作接口。
-- `Acquire(TKey key)`: 从指定键的对象池中获取一个对象
-- `Release(TKey key, TObject obj)`: 将对象释放回指定键的对象池
-- `Clear()`: 清空所有对象池
+```csharp
+public interface IObjectPoolSystem
+ where TObject : IPoolableObject
+ where TKey : notnull
+{
+ ///
+ /// 从指定键的对象池中获取一个对象
+ ///
+ /// 对象池的键值
+ /// 获取到的对象实例
+ TObject Acquire(TKey key);
+
+ ///
+ /// 将对象释放回指定键的对象池中
+ ///
+ /// 对象池的键值
+ /// 需要释放的对象
+ void Release(TKey key, TObject obj);
+
+ ///
+ /// 清空所有对象池,销毁所有池中的对象
+ ///
+ void Clear();
+}
+```
### AbstractObjectPoolSystem 抽象类
-实现了 IObjectPoolSystem 接口的具体逻辑:
+实现了 `IObjectPoolSystem` 接口的具体逻辑,提供了对象池管理的完整实现。
+
+**核心特性:**
- 使用字典存储多个对象池,以键区分不同的对象池
+- 使用栈(Stack)存储池中的对象,实现 LIFO(后进先出)管理
- 提供获取和释放对象的方法
-- 通过抽象方法 Create 让子类决定如何创建对象
+- 通过抽象方法 `Create` 让子类决定如何创建对象
- 在系统销毁时自动清理所有对象池
-## 设计特点
+**内部实现:**
-1. **类型安全**: 使用泛型参数确保类型安全
-2. **多池管理**: 支持使用不同键管理多个对象池
-3. **生命周期管理**: 通过接口方法精确控制对象的生命周期
-4. **内存效率**: 通过复用对象减少内存分配和垃圾回收
+```csharp
+public abstract class AbstractObjectPoolSystem
+ : AbstractSystem, IObjectPoolSystem
+ where TObject : IPoolableObject
+ where TKey : notnull
+{
+ // 存储对象池的字典,键为池标识,值为对应类型的对象栈
+ protected readonly Dictionary> Pools = new();
-## 工作原理
+ // 获取对象
+ public TObject Acquire(TKey key)
+ {
+ if (!Pools.TryGetValue(key, out var pool))
+ {
+ pool = new Stack();
+ Pools[key] = pool;
+ }
-1. **获取对象** (Acquire): 如果池中有可用对象,则从池中取出;否则创建新对象
-2. **释放对象** (Release): 调用对象的 OnRelease 方法后将其放回池中
-3. **创建对象**: 通过抽象方法 Create 由子类实现具体的创建逻辑
-4. **清理**: 在系统销毁时调用 OnDestroy 方法清理所有对象池
+ var obj = pool.Count > 0
+ ? pool.Pop() // 从池中取出
+ : Create(key); // 创建新对象
+
+ obj.OnAcquire(); // 调用对象的获取钩子
+ return obj;
+ }
+
+ // 释放对象
+ public void Release(TKey key, TObject obj)
+ {
+ obj.OnRelease(); // 调用对象的释放钩子
+
+ if (!Pools.TryGetValue(key, out var pool))
+ {
+ pool = new Stack();
+ Pools[key] = pool;
+ }
+
+ pool.Push(obj); // 放回池中
+ }
+
+ // 清空所有对象池
+ public void Clear()
+ {
+ foreach (var obj in Pools.Values.SelectMany(pool => pool))
+ {
+ obj.OnPoolDestroy(); // 调用对象的销毁钩子
+ }
+
+ Pools.Clear();
+ }
+
+ // 子类实现:创建新对象
+ protected abstract TObject Create(TKey key);
+
+ // 系统销毁时自动清空对象池
+ protected override void OnDestroy()
+ {
+ Clear();
+ }
+}
+```
+
+## 基本使用
+
+### 1. 定义池化对象
+
+首先,创建一个实现 `IPoolableObject` 接口的类。
+
+```csharp
+public class Bullet : IPoolableObject
+{
+ public int Damage { get; private set; }
+ public float Speed { get; private set; }
+ public Vector3 Position { get; private set; }
+ public Vector3 Direction { get; private set; }
+ public bool IsActive { get; private set; }
+
+ public void OnAcquire()
+ {
+ // 从池中获取时调用,初始化对象状态
+ IsActive = true;
+ }
+
+ public void OnRelease()
+ {
+ // 放回池中时调用,清理对象状态
+ IsActive = false;
+ Damage = 0;
+ Speed = 0;
+ Position = Vector3.Zero;
+ Direction = Vector3.Zero;
+ }
+
+ public void OnPoolDestroy()
+ {
+ // 对象池销毁时调用,执行最终清理
+ // 可以在这里释放非托管资源
+ }
+
+ // 设置子弹属性的方法
+ public void Setup(int damage, float speed, Vector3 position, Vector3 direction)
+ {
+ Damage = damage;
+ Speed = speed;
+ Position = position;
+ Direction = direction;
+ }
+
+ // 更新子弹逻辑
+ public void Update(float deltaTime)
+ {
+ Position += Direction * Speed * deltaTime;
+ }
+}
+```
+
+### 2. 实现对象池系统
+
+继承 `AbstractObjectPoolSystem` 并实现 `Create` 方法。
+
+```csharp
+public class BulletPoolSystem : AbstractObjectPoolSystem
+{
+ protected override Bullet Create(string key)
+ {
+ // 根据键值创建不同类型的子弹
+ return key switch
+ {
+ "standard" => new Bullet(),
+ "heavy" => new Bullet(),
+ "explosive" => new Bullet(),
+ _ => new Bullet()
+ };
+ }
+
+ protected override void OnInit()
+ {
+ // 可以预先创建一些对象放入池中
+ for (int i = 0; i < 10; i++)
+ {
+ var bullet = Create("standard");
+ bullet.OnAcquire();
+ bullet.OnRelease();
+ Release("standard", bullet);
+ }
+ }
+}
+```
+
+### 3. 在架构中注册对象池系统
+
+```csharp
+public class GameArchitecture : Architecture
+{
+ protected override void Init()
+ {
+ // 注册其他组件
+ RegisterModel(new PlayerModel());
+ RegisterSystem(new CombatSystem());
+
+ // 注册对象池系统
+ RegisterSystem(new BulletPoolSystem());
+ }
+}
+```
+
+### 4. 使用对象池
+
+```csharp
+public class ShootingSystem : AbstractSystem
+{
+ private BulletPoolSystem _bulletPool;
+ private List _activeBullets = new();
+
+ protected override void OnInit()
+ {
+ _bulletPool = this.GetSystem();
+ this.RegisterEvent(OnShoot);
+ this.RegisterEvent(OnUpdate);
+ }
+
+ private void OnShoot(ShootEvent e)
+ {
+ // 从对象池获取子弹
+ var bullet = _bulletPool.Acquire("standard");
+
+ // 设置子弹属性
+ bullet.Setup(
+ damage: e.Damage,
+ speed: 10.0f,
+ position: e.StartPosition,
+ direction: e.Direction
+ );
+
+ // 添加到活跃列表
+ _activeBullets.Add(bullet);
+ }
+
+ private void OnUpdate(GameUpdateEvent e)
+ {
+ // 更新所有活跃子弹
+ for (int i = _activeBullets.Count - 1; i >= 0; i--)
+ {
+ var bullet = _activeBullets[i];
+ bullet.Update(e.DeltaTime);
+
+ // 检查子弹是否需要销毁(例如:超出范围或击中目标)
+ if (ShouldDestroyBullet(bullet))
+ {
+ // 放回对象池
+ _bulletPool.Release("standard", bullet);
+ _activeBullets.RemoveAt(i);
+ }
+ }
+ }
+
+ private bool ShouldDestroyBullet(Bullet bullet)
+ {
+ // 简单示例:子弹超出一定范围则销毁
+ return bullet.Position.Length() > 1000.0f;
+ }
+}
+```
+
+## 高级用法
+
+### 1. 多键对象池管理
+
+```csharp
+public class ParticlePoolSystem : AbstractObjectPoolSystem
+{
+ protected override Particle Create(string key)
+ {
+ // 根据键值创建不同类型的粒子效果
+ return key switch
+ {
+ "explosion" => new Particle(explosionPrefab),
+ "smoke" => new Particle(smokePrefab),
+ "spark" => new Particle(sparkPrefab),
+ _ => throw new ArgumentException($"Unknown particle type: {key}")
+ };
+ }
+
+ // 提供便捷方法
+ public Particle SpawnExplosion(Vector3 position)
+ {
+ var particle = Acquire("explosion");
+ particle.Position = position;
+ particle.Play();
+ return particle;
+ }
+}
+
+// 使用
+public class EffectSystem : AbstractSystem
+{
+ private ParticlePoolSystem _particlePool;
+
+ protected override void OnInit()
+ {
+ _particlePool = this.GetSystem();
+ }
+
+ public void PlayExplosion(Vector3 position)
+ {
+ _particlePool.SpawnExplosion(position);
+ }
+}
+```
+
+### 2. 动态对象池管理
+
+```csharp
+public class EnemyPoolSystem : AbstractObjectPoolSystem
+{
+ protected override Enemy Create(string key)
+ {
+ // 根据敌人类型创建不同的敌人
+ var enemyPrefab = LoadEnemyPrefab(key);
+ return new Enemy(enemyPrefab);
+ }
+
+ // 动态注册新的敌人类型池
+ public void RegisterEnemyType(string enemyType)
+ {
+ if (!Pools.ContainsKey(enemyType))
+ {
+ Pools[enemyType] = new Stack();
+
+ // 预热:预先创建几个敌人放入池中
+ for (int i = 0; i < 3; i++)
+ {
+ var enemy = Create(enemyType);
+ enemy.OnAcquire();
+ enemy.OnRelease();
+ Release(enemyType, enemy);
+ }
+ }
+ }
+}
+
+// 使用
+public class EnemySpawnerSystem : AbstractSystem
+{
+ private EnemyPoolSystem _enemyPool;
+
+ protected override void OnInit()
+ {
+ _enemyPool = this.GetSystem();
+
+ // 注册不同类型的敌人
+ _enemyPool.RegisterEnemyType("goblin");
+ _enemyPool.RegisterEnemyType("orc");
+ _enemyPool.RegisterEnemyType("dragon");
+ }
+
+ public void SpawnEnemy(string enemyType, Vector3 position)
+ {
+ var enemy = _enemyPool.Acquire(enemyType);
+ enemy.Position = position;
+ enemy.Activate();
+ }
+}
+```
+
+### 3. 对象池大小限制
+
+```csharp
+public class LimitedBulletPoolSystem : AbstractObjectPoolSystem
+{
+ private const int MaxPoolSize = 50;
+
+ protected override Bullet Create(string key)
+ {
+ return new Bullet();
+ }
+
+ public new void Release(string key, Bullet obj)
+ {
+ // 检查对象池大小
+ if (Pools.TryGetValue(key, out var pool) && pool.Count >= MaxPoolSize)
+ {
+ // 池已满,不回收对象,让它被 GC 回收
+ return;
+ }
+
+ // 调用基类的 Release 方法
+ base.Release(key, obj);
+ }
+}
+```
+
+### 4. 对象池统计和调试
+
+```csharp
+public class DebuggablePoolSystem : AbstractObjectPoolSystem
+{
+ public Dictionary PoolSizes => Pools.ToDictionary(
+ kvp => kvp.Key,
+ kvp => kvp.Value.Count
+ );
+
+ public int TotalPooledObjects => Pools.Values.Sum(stack => stack.Count);
+
+ public void LogPoolStatus()
+ {
+ foreach (var (key, stack) in Pools)
+ {
+ Console.WriteLine($"Pool [{key}]: {stack.Count} objects");
+ }
+
+ Console.WriteLine($"Total pooled objects: {TotalPooledObjects}");
+ }
+
+ protected override void OnDestroy()
+ {
+ LogPoolStatus();
+ base.OnDestroy();
+ }
+}
+```
## 使用场景
-- 频繁创建和销毁的临时对象
-- 高性能要求的系统,需要减少GC压力
-- 对象创建成本较高的情况
\ No newline at end of file
+### 1. 游戏对象池
+
+**适用对象:**
+- 子弹、箭矢、投射物
+- 敌人、NPC
+- 爆炸效果、粒子系统
+- UI 元素(提示、对话框)
+
+**示例:子弹池**
+
+```csharp
+// 定义子弹
+public class Bullet : IPoolableObject
+{
+ public Vector3 Position { get; private set; }
+ public Vector3 Velocity { get; private set; }
+ public float Lifetime { get; private set; }
+
+ public void OnAcquire()
+ {
+ Lifetime = 5.0f; // 5秒后自动销毁
+ }
+
+ public void OnRelease()
+ {
+ Position = Vector3.Zero;
+ Velocity = Vector3.Zero;
+ }
+
+ public void OnPoolDestroy() { }
+
+ public void Update(float deltaTime)
+ {
+ Position += Velocity * deltaTime;
+ Lifetime -= deltaTime;
+ }
+}
+
+// 子弹对象池
+public class BulletPoolSystem : AbstractObjectPoolSystem
+{
+ protected override Bullet Create(string key) => new Bullet();
+}
+
+// 射击系统
+public class ShootingSystem : AbstractSystem
+{
+ private BulletPoolSystem _bulletPool;
+ private List _activeBullets = new();
+
+ protected override void OnInit()
+ {
+ _bulletPool = this.GetSystem();
+ this.RegisterEvent(OnShoot);
+ this.RegisterEvent(OnUpdate);
+ }
+
+ private void OnShoot(ShootEvent e)
+ {
+ var bullet = _bulletPool.Acquire("normal");
+ bullet.Position = e.StartPosition;
+ bullet.Velocity = e.Direction * e.Speed;
+ _activeBullets.Add(bullet);
+ }
+
+ private void OnUpdate(GameUpdateEvent e)
+ {
+ for (int i = _activeBullets.Count - 1; i >= 0; i--)
+ {
+ var bullet = _activeBullets[i];
+ bullet.Update(e.DeltaTime);
+
+ if (bullet.Lifetime <= 0)
+ {
+ _bulletPool.Release("normal", bullet);
+ _activeBullets.RemoveAt(i);
+ }
+ }
+ }
+}
+```
+
+### 2. UI 元素池
+
+**适用对象:**
+- 对话框
+- 提示框
+- 菜单项
+- 列表项
+
+**示例:提示框池**
+
+```csharp
+public class Tooltip : IPoolableObject
+{
+ public string Text { get; set; }
+ public bool IsActive { get; private set; }
+
+ public void OnAcquire()
+ {
+ IsActive = true;
+ }
+
+ public void OnRelease()
+ {
+ IsActive = false;
+ Text = "";
+ }
+
+ public void OnPoolDestroy() { }
+
+ public void Show(string text, Vector3 position)
+ {
+ Text = text;
+ // 更新 UI 位置和内容
+ }
+}
+
+public class TooltipPoolSystem : AbstractObjectPoolSystem
+{
+ protected override Tooltip Create(string key) => new Tooltip();
+}
+
+public class UISystem : AbstractSystem
+{
+ private TooltipPoolSystem _tooltipPool;
+
+ protected override void OnInit()
+ {
+ _tooltipPool = this.GetSystem();
+ }
+
+ public void ShowTooltip(string text, Vector3 position)
+ {
+ var tooltip = _tooltipPool.Acquire("default");
+ tooltip.Show(text, position);
+ }
+}
+```
+
+### 3. 网络消息对象池
+
+**适用对象:**
+- 网络包
+- 协议消息
+- 数据包
+
+**示例:网络包池**
+
+```csharp
+public class NetworkPacket : IPoolableObject
+{
+ public byte[] Data { get; private set; }
+ public int Length { get; private set; }
+
+ public void OnAcquire()
+ {
+ Data = Array.Empty();
+ Length = 0;
+ }
+
+ public void OnRelease()
+ {
+ // 清理敏感数据
+ if (Data != null)
+ {
+ Array.Clear(Data, 0, Data.Length);
+ }
+ Length = 0;
+ }
+
+ public void OnPoolDestroy() { }
+
+ public void SetData(byte[] data)
+ {
+ Data = data;
+ Length = data.Length;
+ }
+}
+
+public class PacketPoolSystem : AbstractObjectPoolSystem
+{
+ protected override NetworkPacket Create(string key) => new NetworkPacket();
+}
+```
+
+## 最佳实践
+
+### 1. 对象生命周期管理
+
+```csharp
+// ✅ 好的做法:确保所有对象都放回池中
+public class BulletSystem : AbstractSystem
+{
+ private List _activeBullets = new();
+
+ protected override void OnDestroy()
+ {
+ // 系统销毁时,确保所有活跃子弹都放回池中
+ foreach (var bullet in _activeBullets)
+ {
+ _bulletPool.Release("standard", bullet);
+ }
+
+ _activeBullets.Clear();
+ base.OnDestroy();
+ }
+}
+
+// ❌ 不好的做法:忘记放回对象,导致泄漏
+public class BadBulletSystem : AbstractSystem
+{
+ private List _activeBullets = new();
+
+ private void OnUpdate(GameUpdateEvent e)
+ {
+ // 子弹销毁时忘记放回池中
+ if (bullet.Lifetime <= 0)
+ {
+ _activeBullets.RemoveAt(i);
+ // 忘记调用 _bulletPool.Release(...)
+ }
+ }
+}
+```
+
+### 2. 对象状态重置
+
+```csharp
+// ✅ 好的做法:在 OnRelease 中彻底重置对象状态
+public class Bullet : IPoolableObject
+{
+ public int Damage { get; set; }
+ public float Speed { get; set; }
+ public List Tags { get; set; }
+ public Dictionary Data { get; set; }
+
+ public void OnRelease()
+ {
+ // 重置所有属性
+ Damage = 0;
+ Speed = 0;
+ Tags?.Clear();
+ Data?.Clear();
+
+ // 也可以设置为新实例(如果性能允许)
+ Tags = new List();
+ Data = new Dictionary();
+ }
+}
+
+// ❌ 不好的做法:不完全重置状态
+public class BadBullet : IPoolableObject
+{
+ public List Tags = new List();
+
+ public void OnRelease()
+ {
+ // 只清空列表,但列表实例本身保留
+ // 这可能导致问题:如果其他代码持有列表引用
+ Tags.Clear();
+ }
+}
+```
+
+### 3. 对象池预热
+
+```csharp
+// ✅ 好的做法:预先创建一些对象放入池中
+public class BulletPoolSystem : AbstractObjectPoolSystem
+{
+ protected override Bullet Create(string key) => new Bullet();
+
+ protected override void OnInit()
+ {
+ // 为常用的子弹类型预热对象池
+ var commonTypes = new[] { "standard", "heavy", "sniper" };
+
+ foreach (var type in commonTypes)
+ {
+ // 预先创建 5 个对象
+ for (int i = 0; i < 5; i++)
+ {
+ var bullet = Create(type);
+ bullet.OnAcquire();
+ bullet.OnRelease();
+ Release(type, bullet);
+ }
+ }
+ }
+}
+```
+
+### 4. 对象池大小管理
+
+```csharp
+// ✅ 好的做法:限制对象池大小,避免内存浪费
+public class BoundedPoolSystem : AbstractObjectPoolSystem
+{
+ private const int MaxPoolSize = 100;
+
+ public new void Release(string key, PooledObject obj)
+ {
+ if (Pools.TryGetValue(key, out var pool) && pool.Count >= MaxPoolSize)
+ {
+ // 池已满,不回收对象
+ return;
+ }
+
+ base.Release(key, obj);
+ }
+}
+
+// ✅ 好的做法:动态调整对象池大小
+public class AdaptivePoolSystem : AbstractObjectPoolSystem
+{
+ private Dictionary _peakUsage = new();
+
+ public new void Release(string key, PooledObject obj)
+ {
+ // 记录峰值使用量
+ if (Pools.TryGetValue(key, out var pool))
+ {
+ _peakUsage[key] = Math.Max(_peakUsage.GetValueOrDefault(key, 0), pool.Count);
+ }
+
+ // 根据使用情况动态调整
+ int maxAllowed = _peakUsage.GetValueOrDefault(key, 10) * 2;
+ if (pool.Count >= maxAllowed)
+ {
+ return; // 不回收
+ }
+
+ base.Release(key, obj);
+ }
+}
+```
+
+### 5. 调试和监控
+
+```csharp
+// ✅ 好的做法:添加对象池统计功能
+public class MonitoredPoolSystem : AbstractObjectPoolSystem
+{
+ private Dictionary _acquireCount = new();
+ private Dictionary _releaseCount = new();
+
+ public new PooledObject Acquire(string key)
+ {
+ _acquireCount[key] = _acquireCount.GetValueOrDefault(key, 0) + 1;
+ return base.Acquire(key);
+ }
+
+ public new void Release(string key, PooledObject obj)
+ {
+ _releaseCount[key] = _releaseCount.GetValueOrDefault(key, 0) + 1;
+ base.Release(key, obj);
+ }
+
+ public void PrintStatistics()
+ {
+ foreach (var key in Pools.Keys)
+ {
+ int acquired = _acquireCount.GetValueOrDefault(key, 0);
+ int released = _releaseCount.GetValueOrDefault(key, 0);
+ int leaked = acquired - released;
+
+ Console.WriteLine($"Pool [{key}]:");
+ Console.WriteLine($" Acquired: {acquired}");
+ Console.WriteLine($" Released: {released}");
+ Console.WriteLine($" Leaked: {leaked}");
+ Console.WriteLine($" Pool size: {Pools[key].Count}");
+ }
+ }
+}
+```
+
+## 性能优化
+
+### 1. 减少对象创建
+
+```csharp
+// ✅ 好的做法:对象池预热,避免运行时创建
+public class PreheatedPoolSystem : AbstractObjectPoolSystem
+{
+ protected override Bullet Create(string key) => new Bullet();
+
+ protected override void OnInit()
+ {
+ // 预热常用对象池
+ PreheatPool("standard", 20);
+ PreheatPool("heavy", 10);
+ }
+
+ private void PreheatPool(string key, int count)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ var bullet = Create(key);
+ bullet.OnAcquire();
+ bullet.OnRelease();
+ Release(key, bullet);
+ }
+ }
+}
+```
+
+### 2. 使用值类型作为键
+
+```csharp
+// ✅ 好的做法:使用枚举或整数作为键,避免字符串比较
+public enum BulletType
+{
+ Standard,
+ Heavy,
+ Explosive
+}
+
+public class FastBulletPoolSystem : AbstractObjectPoolSystem
+{
+ protected override Bullet Create(BulletType key) => key switch
+ {
+ BulletType.Standard => new Bullet(),
+ BulletType.Heavy => new Bullet(),
+ BulletType.Explosive => new Bullet(),
+ _ => throw new ArgumentException()
+ };
+}
+```
+
+### 3. 批量操作
+
+```csharp
+// ✅ 好的做法:批量获取和释放对象
+public class BatchPoolSystem : AbstractObjectPoolSystem
+{
+ public List AcquireBatch(string key, int count)
+ {
+ var objects = new List(count);
+ for (int i = 0; i < count; i++)
+ {
+ objects.Add(Acquire(key));
+ }
+ return objects;
+ }
+
+ public void ReleaseBatch(string key, IEnumerable objects)
+ {
+ foreach (var obj in objects)
+ {
+ Release(key, obj);
+ }
+ }
+}
+```
+
+## 注意事项
+
+1. **对象状态管理**:确保 `OnRelease` 方法彻底重置对象状态,避免状态污染
+2. **对象引用**:不要在放回对象池后继续持有对象引用
+3. **线程安全**:对象池本身不是线程安全的,如需多线程访问,需要自行加锁
+4. **内存泄漏**:确保所有获取的对象最终都放回池中
+5. **对象池大小**:合理设置对象池大小,避免内存浪费或频繁创建
+
+## 相关包
+
+- [`system`](../system/README.md) - 对象池系统继承自 AbstractSystem
+- [`architecture`](../architecture/README.md) - 在架构中注册对象池系统
+
+---
+
+**许可证**: Apache 2.0