引子
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对标准构造器进行封装的过程中引入了对象缓存机制,执行效率会更高。