GFramework/GFramework.Core/pool/AbstractObjectPoolSystem.cs
GeWuYou eb763a9bc4 feat(pool): 重构对象池系统增加统计和容量控制功能
- 引入 PoolInfo 类来管理对象池的核心数据结构和统计信息
- 添加对象池容量限制功能,超过容量时自动销毁多余对象
- 实现对象池统计功能,跟踪创建、获取、释放、销毁等操作计数
- 新增 GetPoolSize 和 GetActiveCount 方法获取池状态信息
- 添加 SetMaxCapacity 方法设置池的最大容量限制
- 实现 Prewarm 功能用于预创建对象提高性能
- 提供 GetStatistics 方法获取详细的池统计信息
- 添加 IsExternalInit 支持旧版 .NET 框架的 init-only 属性
- 扩展 ArrayPool 添加便捷的扩展方法和自动释放功能
- 新增 StringBuilderPool 提供高性能的字符串构建器复用
- 完善单元测试覆盖新增的所有功能特性
2026-02-25 20:40:02 +08:00

245 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using GFramework.Core.Abstractions.pool;
using GFramework.Core.system;
namespace GFramework.Core.pool;
/// <summary>
/// 抽象对象池系统,提供基于键值的对象池管理功能
/// </summary>
/// <typeparam name="TKey">对象池的键类型必须不为null</typeparam>
/// <typeparam name="TObject">池化对象类型必须实现IPoolableObject接口</typeparam>
public abstract class AbstractObjectPoolSystem<TKey, TObject>
: AbstractSystem, IObjectPoolSystem<TKey, TObject> where TObject : IPoolableObject where TKey : notnull
{
/// <summary>
/// 池信息类,用于管理对象池的核心数据结构和统计信息。
/// 包含对象栈、容量限制以及各类操作的统计计数。
/// </summary>
protected class PoolInfo
{
/// <summary>
/// 对象栈,用于存储可复用的对象实例。
/// </summary>
public Stack<TObject> Stack { get; } = new();
/// <summary>
/// 池的最大容量限制,超过此数量时将不再创建新对象。
/// </summary>
public int MaxCapacity { get; set; }
/// <summary>
/// 总共创建的对象数量统计。
/// </summary>
public int TotalCreated { get; set; }
/// <summary>
/// 总共从池中获取的对象数量统计。
/// </summary>
public int TotalAcquired { get; set; }
/// <summary>
/// 总共归还到池中的对象数量统计。
/// </summary>
public int TotalReleased { get; set; }
/// <summary>
/// 总共销毁的对象数量统计。
/// </summary>
public int TotalDestroyed { get; set; }
/// <summary>
/// 当前活跃(正在使用)的对象数量统计。
/// </summary>
public int ActiveCount { get; set; }
}
/// <summary>
/// 存储对象池的字典,键为池标识,值为池信息
/// </summary>
protected readonly Dictionary<TKey, PoolInfo> Pools = new();
/// <summary>
/// 获取对象池中的对象,如果池中没有可用对象则创建新的对象
/// </summary>
/// <param name="key">对象池的键值</param>
/// <returns>获取到的对象实例</returns>
public TObject Acquire(TKey key)
{
if (!Pools.TryGetValue(key, out var poolInfo))
{
poolInfo = new PoolInfo();
Pools[key] = poolInfo;
}
TObject obj;
if (poolInfo.Stack.Count > 0)
{
obj = poolInfo.Stack.Pop();
}
else
{
obj = Create(key);
poolInfo.TotalCreated++;
}
poolInfo.TotalAcquired++;
poolInfo.ActiveCount++;
obj.OnAcquire();
return obj;
}
/// <summary>
/// 将对象释放回对象池中
/// </summary>
/// <param name="key">对象池的键值</param>
/// <param name="obj">需要释放的对象</param>
public void Release(TKey key, TObject obj)
{
obj.OnRelease();
if (!Pools.TryGetValue(key, out var poolInfo))
{
poolInfo = new PoolInfo();
Pools[key] = poolInfo;
}
poolInfo.TotalReleased++;
poolInfo.ActiveCount--;
// 检查容量限制
if (poolInfo.MaxCapacity > 0 && poolInfo.Stack.Count >= poolInfo.MaxCapacity)
{
// 超过容量限制,销毁对象
obj.OnPoolDestroy();
poolInfo.TotalDestroyed++;
}
else
{
poolInfo.Stack.Push(obj);
}
}
/// <summary>
/// 清空所有对象池,销毁所有池中的对象并清理池容器
/// </summary>
public void Clear()
{
// 遍历所有对象池,调用每个对象的销毁方法
foreach (var poolInfo in Pools.Values)
{
foreach (var obj in poolInfo.Stack)
{
obj.OnPoolDestroy();
}
}
Pools.Clear();
}
/// <summary>
/// 获取指定池的当前大小
/// </summary>
/// <param name="key">对象池的键</param>
/// <returns>池中可用对象的数量</returns>
public int GetPoolSize(TKey key)
{
return Pools.TryGetValue(key, out var poolInfo) ? poolInfo.Stack.Count : 0;
}
/// <summary>
/// 获取指定池的活跃对象数量
/// </summary>
/// <param name="key">对象池的键</param>
/// <returns>已被获取但未释放的对象数量</returns>
public int GetActiveCount(TKey key)
{
return Pools.TryGetValue(key, out var poolInfo) ? poolInfo.ActiveCount : 0;
}
/// <summary>
/// 设置指定池的最大容量
/// </summary>
/// <param name="key">对象池的键</param>
/// <param name="maxCapacity">最大容量,超过此容量的对象将被销毁而不是放回池中</param>
public void SetMaxCapacity(TKey key, int maxCapacity)
{
if (!Pools.TryGetValue(key, out var poolInfo))
{
poolInfo = new PoolInfo();
Pools[key] = poolInfo;
}
poolInfo.MaxCapacity = maxCapacity;
}
/// <summary>
/// 预热对象池,提前创建指定数量的对象
/// </summary>
/// <param name="key">对象池的键</param>
/// <param name="count">要预创建的对象数量</param>
public void Prewarm(TKey key, int count)
{
if (!Pools.TryGetValue(key, out var poolInfo))
{
poolInfo = new PoolInfo();
Pools[key] = poolInfo;
}
for (var i = 0; i < count; i++)
{
var obj = Create(key);
poolInfo.TotalCreated++;
obj.OnRelease();
poolInfo.Stack.Push(obj);
}
}
/// <summary>
/// 获取指定池的统计信息
/// </summary>
/// <param name="key">对象池的键</param>
/// <returns>池的统计信息</returns>
public PoolStatistics GetStatistics(TKey key)
{
if (!Pools.TryGetValue(key, out var poolInfo))
{
return new PoolStatistics
{
AvailableCount = 0,
ActiveCount = 0,
MaxCapacity = 0,
TotalCreated = 0,
TotalAcquired = 0,
TotalReleased = 0,
TotalDestroyed = 0
};
}
return new PoolStatistics
{
AvailableCount = poolInfo.Stack.Count,
ActiveCount = poolInfo.ActiveCount,
MaxCapacity = poolInfo.MaxCapacity,
TotalCreated = poolInfo.TotalCreated,
TotalAcquired = poolInfo.TotalAcquired,
TotalReleased = poolInfo.TotalReleased,
TotalDestroyed = poolInfo.TotalDestroyed
};
}
/// <summary>
/// 创建一个新的对象实例(由子类决定怎么创建)
/// </summary>
/// <param name="key">用于创建对象的键值</param>
/// <returns>新创建的对象实例</returns>
protected abstract TObject Create(TKey key);
/// <summary>
/// 系统销毁时的清理操作,清空所有对象池
/// </summary>
protected override void OnDestroy()
{
Clear();
}
}