构造/析构和空间配置
stl中,采用利用placement new 和主动调用析构函数的方式,将构造/析构函数与实际的内存管理解耦
template <class _T1, class _T2>
inline void _Construct(_T1* __p, const _T2& __value) {
new ((void*) __p) _T1(__value);
}
template <class _T1>
inline void _Construct(_T1* __p) {
new ((void*) __p) _T1();
}
template <class _Tp>
inline void _Destroy(_Tp* __pointer) {
__pointer->~_Tp();
}
一级空间配置器
1、malloc/free
2、实现out-of-memory handler机制
二级空间配置器
目标
避免过多小尺度内存块造成内存碎片,小尺度内存碎片会造成无法回收AND为了管理内存的额外开销占比较大
避免频繁系统调用
总体解决方案
大尺度内存块(>128kb)利用一起空间配置器管理,小尺度内存块利用 freelist + memory pool管理
详细解决方案
FreeList是一个数组,用于维护不同尺度的空闲内存快
长度为128/8,每个元素指向一个链表,链表内每个元素大小为 8*(i + 1)(i为数组下标)
当FreeList中有对应尺度有空闲块时
当FreeList中无对应尺度有空闲块时
为了避免频系统调用,向内存池申请一大块内存(最多20*n),填充对应尺度的FreeList
内存池内存分配逻辑
内存池不释放内存,只为freelist分配内存
- 内存池剩余空间足够直接分配n * nobj
- 内存池剩余空间不太够,能分配几个n分配几个
- 内存池剩余空间完全不够,一个n也不够
- 将内存池目前有的内存分配给对应较小尺度的freelist元素
- 向系统申请2 * n * nobj内存,一半给freeList,一半内存池留着
- 若申请失败
- 向较大尺度freelist元素腾挪空闲空间
- 较大尺度freelist元素也没有空闲空间,调用一级空间配置器,尝试借助out-of-memory机制获取内存