STL的二级空间配置器和malloc

来源:互联网 发布:全球语音翻译软件 编辑:程序博客网 时间:2024/06/07 15:35

前言

最近,有同学接到了阿里的内推电面,而我的简历还躺在简历池里没有人看到,痛定思痛,我不在相信自己的记忆力了,虽然面临秋招,我还是打算把我遇到的重要的问题记下来吧

问题

这个问题就来自于那个同学的面试—-为什么STL的二级空间配置器还要使用malloc,而不是自己向OS申请内存构建内存池。

自己的理解

STL为什么要使用二级空间配置器,侯捷老师的书中已经有详解了,但是ptmalloc本身没有异常处理和内存清理,但是二级配置器中对内存分配的异常都进行了处理(调用oom_mallloc()和oom_realloc()清理内存试图挤出点内存,_THROW_BAD_ALLOC异常),并且在彻底失败时可以调用用户的回调函数。同时,二级空间配置器对内存的管理减少了小区块造成的内存碎片。
另外,malloc是线程安全的,在每次分配整理字块时,要获取锁,效率低。二级配置器提前分配好空间,就不需要每次都获取锁了,因为STL不是线程安全的。
malloc对于需要长生命周期的对象还是不够友好,很容易造成内存暴增,而被OS干掉,以后还是研究一下tcmalloc吧。

自己的延伸

为什么不用new?—答案来自知乎dontpanic
用new也是可以的。operator new有一个只申请特定大小的内存的版本:operator new, operator new[],调用::operator new(num_bytes)就可以了。
operator new在申请内存彻底失败之后,会抛出bad_alloc异常。SGI的allocator在当前这一步(即题主贴出的代码中的malloc调用)失败后,还会尝试用自己的oom_malloc从别的地方挤出一点内存。这用该是上面引用中提到的malloc具有simple faliure detection比较有优势的原因之一。
C++允许用户使用set_new_handler设置内存申请失败时的回调函数。SGI的这个allocator在malloc失败时其实还没有“彻底”申请失败,这个地方要怎么处理也是个麻烦事。

细细的想一下,其实只是STL版本问题,实现问题。

原创粉丝点击