LiSheng's blog LiSheng's blog
首页
笔记
个人简历
随笔集
GitHub (opens new window)
首页
笔记
个人简历
随笔集
GitHub (opens new window)
  • golang

  • cplus

    • 内存相关

    • 面向对象

      • 相关问题
      • 构造、析构顺序
      • 对象内存布局
      • 静态、动态多态
      • 虚函数表
      • 重载、重写、覆盖
      • 构造函数不能是虚函数
      • CRTP模式的原理和用途
      • 移动语义move
      • 构造函数初始化列表
      • 静态成员变量和函数
      • 多重继承
      • 菱形问题与虚继承
      • 对象池
      • STL相关

      • 内置数据结构
      • 数据结构示例
      • go和c++对比
      • 关键字

    • leetcode

    • 存储技术

    • 分布式系统

    • 计算机网络

    • Linux操作系统

    • Redis

    • 其他

    • 笔记
    • cplus
    • 面向对象
    lisheng
    2024-09-10
    目录

    对象池

    # 一、什么是对象池(Object Pool)?

    **对象池(Object Pool)**是一种设计模式,用于管理和重用一组可复用的对象,而不是在需要时频繁地创建和销毁对象。这种模式特别适用于对象创建开销较大、使用频繁但生命周期较短的场景。通过对象池,可以显著减少对象创建和销毁的开销,提高程序的性能。

    在对象池模式中,创建的对象被存储在一个池中。当需要使用某个对象时,从池中获取(租借)该对象;使用完毕后,将该对象返回池中以便再次使用,而不是销毁它。

    # 二、如何在C++中实现一个简单的对象池?

    下面是一个简单的对象池实现示例,针对假设的 MyObject 类进行管理。

    # 1. 定义对象池类

    #include <iostream>
    #include <vector>
    #include <memory>
    
    template <typename T>
    class ObjectPool {
    public:
        // 构造函数,初始化对象池大小
        ObjectPool(size_t poolSize) {
            for (size_t i = 0; i < poolSize; ++i) {
                pool_.push_back(std::make_unique<T>());
            }
        }
    
        // 租借对象
        std::unique_ptr<T> acquire() {
            if (!pool_.empty()) {
                std::unique_ptr<T> obj = std::move(pool_.back());
                pool_.pop_back();
                return obj;
            } else {
                // 池中无可用对象时,动态分配新对象
                return std::make_unique<T>();
            }
        }
    
        // 归还对象
        void release(std::unique_ptr<T> obj) {
            pool_.push_back(std::move(obj));
        }
    
    private:
        std::vector<std::unique_ptr<T>> pool_;
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    # 2. 使用对象池

    class MyObject {
    public:
        MyObject() {
            std::cout << "MyObject created\n";
        }
    
        ~MyObject() {
            std::cout << "MyObject destroyed\n";
        }
    
        void doSomething() {
            std::cout << "Doing something...\n";
        }
    };
    
    int main() {
        ObjectPool<MyObject> pool(2); // 初始化对象池,包含2个对象
    
        {
            auto obj1 = pool.acquire();
            obj1->doSomething();
    
            auto obj2 = pool.acquire();
            obj2->doSomething();
    
            // 此时池中无对象,acquire()会创建新对象
            auto obj3 = pool.acquire();
            obj3->doSomething();
    
            // 释放对象,将其返回池中
            pool.release(std::move(obj1));
            pool.release(std::move(obj2));
            pool.release(std::move(obj3));
        }
    
        // 池中对象再次被租借
        auto obj4 = pool.acquire();
        obj4->doSomething();
    
        return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41

    # 3. 运行结果

    MyObject created
    MyObject created
    Doing something...
    Doing something...
    MyObject created
    Doing something...
    Doing something...
    
    1
    2
    3
    4
    5
    6
    7

    在这个例子中:

    • 对象池被初始化为包含两个 MyObject 实例。当池中对象被租借完后,再调用 acquire() 时将创建新对象。
    • 当对象被归还给池时,它们会被存储以便将来使用,从而避免频繁的创建和销毁。

    # 三、对象池的优缺点

    # 1. 优点

    • 减少开销:通过重用对象,避免了对象的频繁创建和销毁,节省了CPU和内存资源。
    • 提高性能:对于需要频繁创建、销毁的对象(如数据库连接、线程、内存块等),对象池可以显著提高系统的性能。
    • 控制资源:对象池可以限制系统中某类对象的数量,避免资源耗尽(如数据库连接池)。

    # 2. 缺点

    • 复杂性增加:对象池的实现引入了额外的复杂性,尤其是在涉及多线程环境下,需要考虑线程安全问题。
    • 内存占用:对象池可能会长时间持有未被使用的对象,导致内存占用增加。如果对象池管理不善,可能会引起内存泄漏。
    • 生命周期管理:池中的对象需要正确管理其状态,确保对象在租借和归还过程中被正确重置,否则可能导致使用不当的问题。

    # 四、对象池的应用场景

    • 数据库连接池:在数据库驱动程序中广泛使用,以避免每次查询都重新建立数据库连接。
    • 线程池:在多线程编程中,线程池用于重用线程,避免频繁创建和销毁线程带来的开销。
    • 内存池:用于管理一组固定大小的内存块,以避免频繁的动态内存分配和释放。

    # 五、总结

    对象池是一种高效管理资源的设计模式,特别适合频繁使用但开销较大的对象。通过适当地设计和使用对象池,可以显著提高系统的性能并优化资源的使用。然而,在实现时需要小心管理对象的生命周期和池的状态,以避免潜在的复杂性和内存问题。

    编辑 (opens new window)
    上次更新: 2024/09/13, 11:59:12
    菱形问题与虚继承
    map和unorder_map

    ← 菱形问题与虚继承 map和unorder_map→

    最近更新
    01
    ceph分布式存储-对象存储(RGW)搭建
    10-27
    02
    ceph分布式存储-集群客户端连接
    10-27
    03
    ceph分布式存储-管理crushmap
    10-27
    更多文章>
    Theme by Vdoing
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式