对象池
简介
对象池是一个用于优化内存管理和性能的重要组件。它通过重用对象来减少内存分配和垃圾回收,从而提高应用程序性能。
核心功能
对象池定义
csharp
public class ObjectPool: LogicSingleton<ObjectPool>, ISingletonAwake
{
private ConcurrentDictionary<Type, Pool> objPool;
private readonly Func<Type, Pool> AddPoolFunc = type => new Pool(type, 1000);
}
主要API
1. 获取对象
csharp
// 通过泛型类型获取
T obj = ObjectPool.Instance.Fetch<T>();
// 通过具体类型获取
MyClass obj = ObjectPool.Instance.Fetch(typeof(MyClass));
// 不使用池创建新对象
MyClass obj = ObjectPool.Instance.Fetch(typeof(MyClass), false);
2. 回收对象
csharp
// 将对象回收到池中
ObjectPool.Instance.Recycle(obj);
使用示例
1. 基础用法
csharp
// 1. 定义可池化对象
public class MyClass : IPool
{
public bool IsFromPool { get; set; }
// 其他属性和方法
public string Name { get; set; }
public int Value { get; set; }
}
// 2. 获取对象
MyClass obj = ObjectPool.Instance.Fetch<MyClass>();
obj.Name = "测试对象";
obj.Value = 100;
// 3. 使用对象
// ... 使用对象的代码 ...
// 4. 回收对象
ObjectPool.Instance.Recycle(obj);
2. 实际例子
对于工程文件里有一个ListComponent.cs
文件,它实现了一个可池化的泛型列表组件:
csharp
public class ListComponent<T>: List<T>, IDisposable
{
public ListComponent()
{
}
public static ListComponent<T> Create()
{
return ObjectPool.Instance.Fetch(typeof (ListComponent<T>)) as ListComponent<T>;
}
public void Dispose()
{
if (this.Capacity > 64) // 超过64,让gc回收
{
return;
}
this.Clear();
ObjectPool.Instance.Recycle(this);
}
}
这个组件是对象池使用的一个很好的例子:
智能池化管理:
- 通过静态
Create()
方法从对象池中获取实例 - 实现
IDisposable
接口,支持使用using
语句自动回收 - 根据容量智能决定是否回收到对象池
- 通过静态
性能优化:
- 对于容量超过64的列表,直接交给GC处理,避免大对象占用池空间
- 回收前调用
Clear()
清空列表,确保下次使用时是干净的状态
使用示例:
csharp
using (var list = ListComponent<int>.Create())
{
list.Add(1);
list.Add(2);
list.Add(3);
// 使用完毕后自动回收到对象池
}
实现原理
1. 无锁设计
- 使用
ConcurrentDictionary
存储类型特定的对象池 - 使用
ConcurrentQueue
管理池化对象 - 使用
Interlocked
实现无锁操作
2. 快速路径优化
- 维护
FastItem
实现快速对象获取和返回 - 使用
CompareExchange
确保线程安全
3. 容量管理
- 每个类型特定的池都有最大容量限制
- 超出容量的对象将被丢弃进行垃圾回收
最佳实践
使用建议
对象设计:
- 实现
IPool
接口以支持池管理 - 对象应该可重用,避免维护状态
- 回收前重置对象状态
- 实现
性能优化:
- 设置合适的池容量
- 避免频繁创建和销毁大对象
- 使用
using
语句自动管理对象生命周期
并发处理:
- 利用对象池的线程安全特性
- 在异常情况下正确处理对象回收
重要说明
WARNING
- 确保回收的对象不再被引用
- 避免在回收后访问对象
- 注意内存泄漏,确保对象被正确回收
- 池化对象应该是轻量级的,避免池化大对象
技术支持
获取帮助
- 💬 加入QQ群讨论
(ET框架交流群)
:474643097 - ⭐ 在GitHub上关注项目获取最新更新