动态内存管理详解:malloc/free/new/delete/brk/mmap
c++ 内存获取和释放 new/delete,new[]/delete[]
c 内存获取和释放 malloc/free, calloc/realloc
上述8个函数/操作符是c/c++语言里常用来做动态内存的申请和释放的,要理解这些接口,大概需要
下面几个维度的了解:
1. 了解OS的进程空间模型,一个进程的地址空间,一般划分为内核区、用户区,用户区又划分为栈区、堆区、数据区、代码区。
这里的‘堆区’,‘栈区’,‘数据区’,‘内核区’,其实就是一个虚拟地址区间,动态内存最终都是从OS的'堆区'上获取的。
2. brk、mmap 系统调用
brk系统调用,可以让进程的堆指针增长一定的大小,逻辑上消耗掉一块本进程的虚拟地址区间,malloc向OS获取的内存大小比较小时,将直接通过brk调用获取虚拟地址,结果是将本进程的brk指针推高。
mmap系统调用,可以让进程的虚拟地址区间里切分出一块指定大小的虚拟地址区间vma_struct,并返回给用户态进程,被mmap映射返回的虚拟地址,逻辑上被消耗了,直到用户进程调用munmap,才回收回来。malloc向系统获取比较大的内存时,会通过mmap直接映射一块虚拟地址区间。mmap系统调用用处非常多,比如一个进程的所有动态库文件.so的加载,都需要通过mmap系统调用映射指定大小的虚拟地址区间,然后将.so代码动态映射到这些区域,以供进程其他部分代码访问;另外,多进程通讯,也可以使用mmap,这块另开文章详解。
无论是brk还是mmap返回的都是虚拟地址,在第一次访问这块地址的时候,会触发缺页异常,然后内核为这块虚拟地址申请并映射物理页框,建立页表映射关系,后续对该区间虚拟地址的访问,通过页表获取物理地址,然后就可以在物理内存上读写了。
3. malloc/free 是libc库函数
malloc/free是 libc实现的库函数,主要实现了一套内存管理机制,当其管理的内存不够时,通过brk/mmap等系统调用向内核申请进程的虚拟地址区间,如果其维护的内存能满足malloc调用,则直接返回,free时会将地址块返回空闲链表。
malloc(size) 的时候,这个函数会多分配一块空间,用于保存size变量,free的时候,直接通过指针前移一定大小,就可以获取malloc时保存的size变量,从而free只需要一个指针作为参数就可以了calloc 库函数相当于 malloc + memset(0)
除了libc自带的动态内存管理库malloc, 有时候还可以使用其他的内存管理库替换,比如使用google实现的tcmalloc ,只需要编译进程时链接上 tcmalloc的静态库并包含响应头文件,就可以透明地使用tcmalloc 了,与libc 的malloc相比, tcmalloc 在内存管理上有很多改进,效率和安全性更好。
4. new/new[]/delete/delete[]
new/delete 是c++ 内置的运算符,相当于增强版的malloc/free. c++是兼容c的,一般来说,同样功能的库,c++会在安全性和功能性方面
比c库做更多工作。动态内存管理这块也一样。
new的实现会调用malloc,对于基本类型变量,它只是增加了一个cookie结构, 比如需要new的对象大小是 object_size, 则事实上调用 malloc 的参数是 object_size + cookie, 这个cookie 结构存放的信息包括对象大小,对象前后会包含两个用于检测内存溢出的变量,所有new申请的cookie块会链接成双向链表。由于内置了内存溢出检测,所以比malloc更安全。
对于自定义类型,new会先申请上述的大小空间,然后调用自定义类型的构造函数,对object所在空间进行构造。c++比c强大的一个方面
就是c++编译器可以自动做构造和析构,new运算符会自动计算需要的空间大小,然后根据类型自己调用构造函数,如果存在子类型对象,或者存在继承的基类型,new都会自动调用子类型的构造函数和基类型的构造函数完成构造。同样,delete 操作符根据cookie的size知道object的大小,如果是自定义类型,会调用析构函数对object所在空间进行析构,如果有子类型或继承,自动调用子类型和基类型的析构函数,然后将cookie块从双向链表摘除,最后调用 free_dbg 释放。
new[] 和delete[]是另外两个操作符,用于数组类型的动态内存获取和释放,实现过程类似new/delete
5. 参考
http://blog.csdn.net/ubuntulover/article/details/7581317
http://blog.csdn.net/szlanny/article/details/4249768
动态内存管理详解:malloc/free/new/delete/brk/mmap的更多相关文章
- 动态内存管理:malloc/free/new/delete/brk/mmap
这是我去腾讯面试的时候遇到的一个问题——malloc()是如何申请内存的? c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, c ...
- 转:C/C++内存管理详解 堆 栈
http://chenqx.github.io/2014/09/25/Cpp-Memory-Management/ 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了 ...
- C/C++内存管理详解
内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄 ...
- C/C++内存管理详解 ZZ
内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的 检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存 ...
- C/C++内存管理详解(转)
内存分配方式 简介 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动 ...
- 【转载】C/C++内存管理详解
转自:http://chenqx.github.io/2014/09/25/Cpp-Memory-Management/ 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中 ...
- Apache Spark 内存管理详解(转载)
Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 ...
- spark内存管理详解
Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 ...
- java之 JVM 内存管理详解
一.JVM结构 根据<java虚拟机规范>规定,JVM的基本结构一般如下图所示: 从左图可知,JVM主要包括四个部分: 1.类加载器(ClassLoader):在JVM启动时或者在类运行时 ...
随机推荐
- poj 2579 中位数问题 查找第K大的值
题意:对列数X计算∣Xi – Xj∣组成新数列的中位数. 思路:双重二分搜索 对x排序 如果某数大于 mid+xi 说明在mid后面,这些数的个数小于 n/2 的话说明这个中位数 mid 太大 反之太 ...
- [Link-Cut-Tree][BZOJ2002]弹飞绵羊
题面 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上\(n\)个 ...
- 36-应用Jwtbearer Authentication
新建.net core webapi项目 E:\coding\netcore>dotnet new webapi --name JwtAuthSample 创建需要用到的实体对象类 namesp ...
- 适配IE8+等浏览器的适配播放插件
function myBrowser(){ var userAgent = navigator.userAgent; //ȡ���������userAgent�ַ� var isOpera = us ...
- 平时收集的一些有关UED的团队和个人博客
平时收集的一些有关UED的团队和个人博客 前端团队阿里巴巴 UED -- 我们设计的界面,并没有几十亿的流量,但每天来自上百个国家的百万商人在使用着.阿里巴巴中国站UED -- 阿里巴巴中国站UED成 ...
- javascript类式继承模式#3——借用和设置原型
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 玩转Node.js(三)
玩转Node.js(三) 上一节对于Nodejs的HTTP服务进行了较为详细的解析,而且也学会了将代码进行模块化,模块化以后每个功能都在单独的文件中,有利于代码的维护.接下来,我们要想想如何处理不同的 ...
- cookie不能删除
cookie不仅仅包含一个键值对,还包含域 domain 路径path, 一般domain是请求的地址 www.baidu.com/news.html 那domain就是www.baidu.com ...
- 关于mysqldump备份非事务表的注意事项
Preface We're used to get a logical backup set(whole instance) by simply specifying "-- ...
- SPOJ 149 FSHEEP Fencing in the Sheep ( 计算几何 + 二分 )
以下摘自SPOJ泛做表格: 题意:给定一个星形多边形,而且给出了一个可以看到形内所有点的位置(我们称这个点为观察点),让你判断有多少个点位于多边形内. 时间复杂度:O(mlogn) 将多边形上的点按极 ...