STL源码分析—空间配置器(续)
来源:互联网 发布:网络弱电箱谁会 编辑:程序博客网 时间:2024/05/01 00:46
http://blog.csdn.net/xietingcandice/article/details/39930603
空闲块列表节点的结构
- union obj
- {
- union obj * free_list_link;
- char client_data[1];
- };
注意这里用的是union,从第一个字段看是一个指向相同形式的指针,从第二个字段看,是指向实际区块的指针,这样一物两用,节约了空间
分配算法:
- // 算法:allocate
- // 输入:申请内存的大小size
- // 输出:若分配成功,则返回一个内存的地址,否则返回NULL
- {
- if(size 大于 128)
- 启动第一级分配器直接调用malloc分配所需的内存并返回内存地址;
- else
- {
- 将size向上round up成8的倍数并根据大小从free_list中取对应的表头free_list_head
- if(free_list_head 不为空)
- {
- 从该列表中取下第一个空闲块并调整free_list,返回free_list_head
- }
- else
- {
- 调用refill算法建立空闲块列表并返回所需的内存地址
- }
- }
- }
- // 算法:refill
- // 输入:内存块的大小size
- // 输出:建立空闲块链表并返回第一个可用的内存地址
- {
- 调用chunk_alloc算法分配若干个大小为size的连续内存区域并返回起始地址chunk和成功分配的块数nobj
- if(块数为1)
- 直接返回 chunk;
- else
- {
- 开始在chunk地址块中建立free_list
- 根据size取free_list中对应的表头元素free_list_head
- 将free_list_head 指向chunk中偏移起始地址为size的地址处,即free_list_head = (obj*)(chunk+size)
- 再将整个chunk中剩下的nobj-1个内存块串联起来构成一个空闲列表
- 返回chunk,即chunk中第一个空闲的内存块
- }
- }
- // 算法:chunk_alloc
- // 输入:内存块的大小size,预分配的内存块数nobj(以引用传递)
- // 输出:一块连续的内存区域的地址和该区域内可以容纳的内存块的块数
- {
- 计算总共所需的内存大小total_bytes
- if(内存池足以分配,即end_free-start_free >= total_bytes)
- {
- 则更新start_free
- 返回旧的start_free
- }
- else if(内存池不够分配nobj个内存块,但至少可以分配一个)
- {
- 计算可以分配的内存块数并修改nobj
- 更新start_free并返回原来的start_free
- }
- else // 内存池连一个内存块都分配不了
- {
- 先将内存池的内存块链入到对应的free_list中后
- 调用malloc操作重新分配内存池,大小为2倍的total_bytes为附加量,start_free指向返回的内存地址
- if(分配不成功)
- {
- if(16个空闲列表中尚有空闲块)
- 尝试将16个空闲列表中空闲块回收到内存池中再调用chunk_alloc(size,nobj)
- else
- 调用第一级分配器尝试out of memory机制是否还有用
- }
- 更新end_free为start_free+total_bytes,heap_size为2倍的total_bytes
- 调用chunk_alloc(size,nobj)
- }
- }
- // 算法:deallocate
- // 输入:需要释放的内存块地址p和大小size
- {
- if(size 大于128字节)
- 直接调用free(p)释放
- else
- {
- 将size向上取8的倍数,并据此获取对应的空闲列表表头指针free_list_head
- 调整free_list_head将p链入空闲列表块中
- }
- }
从free list取内存块给用户,和将区块回收放入free list的过程
多线程环境下内存池互斥访问
在第二级配置器中,存在着多线程环境的内存池管理,解决多线程环境下内存池互斥访问,需在自由链表free_list中进行修改调整,我们从SGI STL第二级配置器源码中看到,嵌套一个类class _Lock ,该类的作用是解决互斥访问,并且只有两个函数:构造函数和析构函数;使用构造函数对内存池进行加锁,使用析构函数对内存池进行解锁。关于多线程内存池互斥访问的源代码如下:
- #ifdef __STL_THREADS
- # include <stl_threads.h>//包含线程文件
- # define __NODE_ALLOCATOR_THREADS true
- # ifdef __STL_SGI_THREADS
- // We test whether threads are in use before locking.
- // Perhaps this should be moved into stl_threads.h, but that
- // probably makes it harder to avoid the procedure call when
- // it isn't needed.
- extern "C" {
- extern int __us_rsthread_malloc;
- }
- // The above is copied from malloc.h. Including <malloc.h>
- // would be cleaner but fails with certain levels of standard
- // conformance.
- # define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \
- { _S_node_allocator_lock._M_acquire_lock(); }
- # define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \
- { _S_node_allocator_lock._M_release_lock(); }
- # else /* !__STL_SGI_THREADS */
- # define __NODE_ALLOCATOR_LOCK \
- { if (threads) _S_node_allocator_lock._M_acquire_lock(); }//获取锁
- # define __NODE_ALLOCATOR_UNLOCK \
- { if (threads) _S_node_allocator_lock._M_release_lock(); }//释放锁
- # endif
- #else
- // Thread-unsafe
- # define __NODE_ALLOCATOR_LOCK
- # define __NODE_ALLOCATOR_UNLOCK
- # define __NODE_ALLOCATOR_THREADS false
- #endif
- # ifdef __STL_THREADS
- static _STL_mutex_lock _S_node_allocator_lock;//互斥锁变量
- # endif
- // It would be nice to use _STL_auto_lock here. But we
- // don't need the NULL check. And we do need a test whether
- // threads have actually been started.
- class _Lock;
- friend class _Lock;
- class _Lock {//解决内存池在多线程环境下的管理
- public:
- _Lock() { __NODE_ALLOCATOR_LOCK; }
- ~_Lock() { __NODE_ALLOCATOR_UNLOCK; }
- };
http://blog.csdn.net/chenhanzhun/article/details/39153797
http://blog.csdn.net/Hackbuteer1/article/details/7724534
0 0
- STL源码分析—空间配置器(续)
- STL源码分析—空间配置器(续)
- STL源码分析—空间配置器
- STL源码分析—空间配置器
- STL源码分析--第二级空间配置器
- STL空间配置器源码及其分析
- STL源码分析--空间配置器 第一级配置器
- STL 源码分析第二章: 空间配置器理解
- stl--分析空间配置器及源码实现
- 《STL源码剖析》—— 空间配置器(二)
- 《STL源码剖析》—— 空间配置器(三)
- 《STL源码剖析》—— 空间配置器(四)
- 《STL源码剖析》—— 空间配置器(五)
- SGI STL空间配置器(STL源码剖析):
- SGI STL空间配置器(STL源码剖析)
- 《STL源码剖析》STL空间配置器
- STL源码分析--空间配置器的底层实现 (二)
- STL源码剖析——空间配置器和迭代器
- Android开发之自定义View专题(一):自定义柱形图
- STL源码分析—空间配置器
- 【段落梗概】【失控】第一章 人造与天生
- 浅谈C++中的执行
- 从标准输入字符,除小写字母变成大写字母之外,其他照原样输出
- STL源码分析—空间配置器(续)
- win7下第二次装双系统ubuntu时出现的两个问题
- bzoj3294: [Cqoi2011]放棋子 容斥原理
- aria2配置示例
- linux上Eclipse安装svn插件和安装JavaHL
- 列举不同的清除浮动的技巧,并指出它们各自适用的使用场景。
- 使用Eclipse构建Maven的SpringMVC项目
- 蛋纷僮悠饰嗽菇坎忍瓢切装性棠氛
- photoshop最新版百度云下载地址