C++消息总线Mozart:内存管理

引子

mozart++的内存管理,由allocator_type和plain_allocator_type泛型构造器组成。plain_allocator_type是无缓存泛型构造器,allocator_type是有缓存泛型构造器。内存管理功能,位于mozart的mpp_foundation模块。完整代码地址:https://github.com/libmozart/foundation/blob/master/mozart%2B%2B/mpp_foundation/memory.hpp

无缓存泛型类型构造器(plain_allocator_type)

/**
 * 无缓存的泛型类型构造器
 * @tparam T: 构造目标对象的类型
 * @tparam blck_size: 分配的存储块大小
 * @tparam allocator_t: 标准构造器实现
 */
template <typename T, size_t blck_size, template <typename> class allocator_t = allocator>
class plain_allocator_type final 
{
    // 标准类型构造器对象,例如STL的std::allocator
    allocator_t<T> mAlloc; 

public:
    /**
     * 默认构造函数
     */
    plain_allocator_type() = default;

    /**
     * 禁止拷贝构造和移动拷贝构造
     */
    plain_allocator_type(const plain_allocator_type &) = delete;

    plain_allocator_type(plain_allocator_type &&) noexcept = delete;

    /**
     * 类的析构函数
     */
    ~plain_allocator_type() = default;

    /**
     * [inlined] 构造T类型的泛型对象
     * @tparam ArgsT: 泛型对象T的参数列表
     * @param args: 泛型对象构造的构造参数
     * @return 已构造的泛型对象指针
     */
    template <typename... ArgsT>
    inline T *alloc(ArgsT &&... args) 
    {
        // 申请一块sizeof(T)大小的内存块,用于构造泛型对象
        T *ptr = mAlloc.allocate(1); 
        // 在已申请的内存块上,定位构造泛型对象T
        mAlloc.construct(ptr, forward<ArgsT>(args)...);
        return ptr;
    }

    /**
     * [inlined] 回收泛型对象T
     * @param ptr: 泛型对象T的指针
     */
    inline void free(T *ptr) 
    {
        // 调用泛型对象ptr的析构函数ptr.~T()
        mAlloc.destroy(ptr);
        // 释放泛型对象ptr所占用的内存块,归还内存到系统
        mAlloc.deallocate(ptr, 1);
    }
};

有缓存泛型构造器(allocator_type)

template <typename T, size_t blck_size, template <typename> class allocator_t = allocator>
class allocator_type final 
{
    // 大小为blck_size的泛型cache pool
    T *mPool[blck_size];
    // 标准类型构造器对象,例如STL的std::allocator
    allocator_t<T> mAlloc;
    // 缓存存取offset索引
    size_t mOffset = 0;

public:
    allocator_type() 
    {
        // 初始构造大小为0.5 * blck_size的内存对象池
        while (mOffset < 0.5 * blck_size) 
            mPool[mOffset++] = mAlloc.allocate(1);
    }

    allocator_type(const allocator_type &) = delete;

    allocator_type(allocator_type &&) noexcept = delete;

    ~allocator_type() 
    {
        // 释放当前存在的内存对象pool
        while (mOffset > 0)
            mAlloc.deallocate(mPool[--mOffset], 1);
    }

    /**
     * [inlined] 构造T类型的泛型对象
     * @tparam ArgsT: 泛型对象T的参数列表
     * @param args: 泛型对象构造的构造参数
     * @return 已构造的泛型对象指针
     */
    template <typename... ArgsT>
    inline T *alloc(ArgsT &&... args) 
    {
        T *ptr = nullptr;
        // 查询当前缓存是否还有可用内存块,如果未用光就从pool中取一块,否则就调用mAlloc.allocate申请一块
        if (mOffset > 0)
            ptr = mPool[--mOffset];
        else
            ptr = mAlloc.allocate(1);
        // 在内存块ptr上,定位构造T类型泛型对象
        mAlloc.construct(ptr, std::forward<ArgsT>(args)...);
        return ptr;
    }

    /**
     * [inlined] 回收泛型对象T
     * @param ptr: 泛型对象T的指针
     */
    inline void free(T *ptr) 
    {
        // 调用泛型对象ptr的析构函数ptr.~T() 
        mAlloc.destroy(ptr);
        // 如果mOffset索引小于blck_size,将对象归还于pool,否则将对象归还于构造器
        if (mOffset < blck_size)
            mPool[mOffset++] = ptr;
        else
            mAlloc.deallocate(ptr, 1);
    }
};

总结

plain_allocator_type只是对标准构造器进行了简单封装,allocator_type对标准构造器进行封装的过程中引入了对象缓存机制,执行效率会更高。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值