C++内存分配粗略概览

2 篇文章 0 订阅


本文目的

 
  在C++内存分配方面,会见到很多操作:new、delete、new[]、delete[]、operator new、 operator delete、malloc、 free、 STL里的 allocator、deallocator,甚至linux内核中的 slab allocator、kmalloc、vmalloc。 种类繁多,眼花缭乱。本文就大概捋一下整体的关系。


内存分配体系

 
  
在这里插入图片描述
图中是相对明了的,但只是大概的层级关系。还有些特殊情况。

  1. 在我们编写程序时,之前提的所有的分配(系统调用视系统而定)都可以拿来直接用,但是它们之中又分了很多层级。
  2. STL内有自己的allocator,但是有很多种,有些是简单的封装调用了operator new,有些则实现了一个内存池(STL源码剖析里的alloc),而内存池需要内存时根据malloc获取内存。
  3. 我们经常用的new内部是调用operator new 和对象的构造函数。
  4. 全局的operator new 调用了malloc 并且还有malloc失败时的new_handle函数(可以设定)。(operator new可以重载,一般有需求会在类内重载。重载全局的operator new有一定风险,就不细说了)
  5. malloc在不同库中会有不同的实现。glibc中是ptmalloc2,其他库还有各种比较好的实现。并且基本上malloc实现又是一种内存池(比之前提的alloc,要复杂的多,毕竟malloc作用范围比alloc要广的多,也是很多有实力的技术团队在不断研究改进的成果)
  6. 在linux里,malloc底层又调用了系统内的brk和mmap来分配内存。
  7. kmalloc和vmalloc则是linux内核中实现,kmalloc分配物理地址连续且虚拟地址连续的内存,vmalloc分配物理地址不连续,虚拟地址连续的内存。所以vmalloc会慢(与总线协议,DDR硬件本身的特性有关(访问不同块需要预充电等))
  8. kmalloc则是从slab allocator获取内存,而slab则又是一种内存池结构。

  
本文只是粗略的概述了大部分内存分配函数或操作的关系,每种自身又有很多可以深挖的细节。想把它们理清楚,是需要几本书才可以的。特别是不同库中malloc的实现(对于多线程的优化手段,为了分配和回收效率的复杂结构设计,回收的内存碎片的合并技巧,等等)


尾语

  内存分配是C++程序员不得不了解的知识,尤其是当需要实现自己的内存池时,必须要知道底层已经做了哪些工作了,我们在上层写的内存池还能做哪些工作,还需要做哪些工作。不然,很可能你实现的功能,底层已经帮你做了,而你所做的效率可能还不如底层分配的效率,无谓而且有害。

以上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值