STL之 SGI STL 二级空间配置器std::alloc过程

SGI STL 二级空间配置器std::alloc过程

SGI STL的std::alloc、glibc的malloc的区别

  • 内存池:内存池可以通过预先分配一定数量的内存块,形成一个内存块池,当需要分配内存时,直接从内存池中取出一个空闲的内存块,并标记为已使用。当不再需要使用某个内存块时,将其标记为空闲状态,放回内存池中,以供后续使用。通过这种方式,可以减少内存碎片和减轻内存分配的开销,提高内存的分配和释放效率。

  • glibc的malloc:在 Linux 中,malloc 的实现是由 glibc 库提供的,glibc 会将系统调用封装成库函数,并在内部维护内存池等数据结构,以提高 malloc 函数的效率。在 glibc 中,内存池被称为 free list,其实现方式就是将空闲的内存块组织成一个链表,在需要分配内存时,从链表中找到合适的内存块并返回。当内存块被释放时,glibc 会将其插入到对应的 free list 中,以备后续使用。

    • 一般来说:glibc 的 malloc 在分配小于128KB内存时,使用brk()系统调用;大于 128KB 的内存时,会使用 mmap 系统调用来分配内存。
    • 小于128KB内存时,brk()通过移动heap顶指针分配堆内的内存,并维持一个内存池。当分配内存时,如果内存池有空间,则在内存池分配,内存池内存不够时再向堆申请内存扩容。
      • free内存时,进程不会立刻释放内存给操作系统,而是归还到内存池
      • 减少了系统调用,但是会造成内存碎片
    • 大于 128KB 的内存时,mmap()通过匿名私有映射,在文件映射与匿名映射区分配内存。
      • free内存时,直接将内存归还操作系统
      • 会频繁产生系统调用,上下文的切换。
      • 频繁发生缺页中断,会造成消耗CPU
  • std::alloc,二级空间配置器,也实现了内存池,用于管理 STL 中的内存分配和释放。

    • 如果分配的内存小于128bytes,二级配置器;大于128bytes,直接调用一级空间配置器std::malloc_alloc,直接调用malloc的
    • 内存小于128bytes:如果free_lists中对应的free_list内存不够,则向内存池请求分配
      • 默认请求分配20个内存块
      • 如果内存池内存不够,则malloc请求分配内存:请求的内存为实际请求总大小的两倍+附加量

参考:《STL源码剖析》,侯捷

posted @ 2023-04-10 20:09  小小灰迪  阅读(24)  评论(0编辑  收藏  举报