Skip to content

对象池

简介

对象池是一个用于优化内存管理和性能的重要组件。它通过重用对象来减少内存分配和垃圾回收,从而提高应用程序性能。

核心功能

对象池定义

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);
    }
}

这个组件是对象池使用的一个很好的例子:

  1. 智能池化管理

    • 通过静态Create()方法从对象池中获取实例
    • 实现IDisposable接口,支持使用using语句自动回收
    • 根据容量智能决定是否回收到对象池
  2. 性能优化

    • 对于容量超过64的列表,直接交给GC处理,避免大对象占用池空间
    • 回收前调用Clear()清空列表,确保下次使用时是干净的状态
  3. 使用示例

csharp
using (var list = ListComponent<int>.Create())
{
    list.Add(1);
    list.Add(2);
    list.Add(3);
    // 使用完毕后自动回收到对象池
}

实现原理

1. 无锁设计

  • 使用 ConcurrentDictionary 存储类型特定的对象池
  • 使用 ConcurrentQueue 管理池化对象
  • 使用 Interlocked 实现无锁操作

2. 快速路径优化

  • 维护 FastItem 实现快速对象获取和返回
  • 使用 CompareExchange 确保线程安全

3. 容量管理

  • 每个类型特定的池都有最大容量限制
  • 超出容量的对象将被丢弃进行垃圾回收

最佳实践

使用建议

  1. 对象设计

    • 实现 IPool 接口以支持池管理
    • 对象应该可重用,避免维护状态
    • 回收前重置对象状态
  2. 性能优化

    • 设置合适的池容量
    • 避免频繁创建和销毁大对象
    • 使用 using 语句自动管理对象生命周期
  3. 并发处理

    • 利用对象池的线程安全特性
    • 在异常情况下正确处理对象回收

重要说明

WARNING

  1. 确保回收的对象不再被引用
  2. 避免在回收后访问对象
  3. 注意内存泄漏,确保对象被正确回收
  4. 池化对象应该是轻量级的,避免池化大对象

技术支持

获取帮助

  • 💬 加入QQ群讨论 (ET框架交流群):474643097
  • ⭐ 在GitHub上关注项目获取最新更新

Released under the MIT License.