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的更多相关文章

  1. 动态内存管理:malloc/free/new/delete/brk/mmap

    这是我去腾讯面试的时候遇到的一个问题——malloc()是如何申请内存的? c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, c ...

  2. 转:C/C++内存管理详解 堆 栈

    http://chenqx.github.io/2014/09/25/Cpp-Memory-Management/ 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了 ...

  3. C/C++内存管理详解

    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄 ...

  4. C/C++内存管理详解 ZZ

    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的 检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存 ...

  5. C/C++内存管理详解(转)

    内存分配方式 简介 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动 ...

  6. 【转载】C/C++内存管理详解

    转自:http://chenqx.github.io/2014/09/25/Cpp-Memory-Management/ 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中 ...

  7. Apache Spark 内存管理详解(转载)

    Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 ...

  8. spark内存管理详解

    Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 ...

  9. java之 JVM 内存管理详解

    一.JVM结构 根据<java虚拟机规范>规定,JVM的基本结构一般如下图所示: 从左图可知,JVM主要包括四个部分: 1.类加载器(ClassLoader):在JVM启动时或者在类运行时 ...

随机推荐

  1. perl语言入门总结-第4章-子程序

    子程序定义和返回值 sub sum{ print "调用了子程序\n"; $a + $b; #后一行为返回值 } ; ; $s =∑ #34 调用子程序 子程序中的参数,参数固定( ...

  2. urllib使用一

    urllib.urlopen()方法: 参数: 1.url(要访问的网页链接http:或者是本地文件file:) 2.data(如果有,就会由GET方法变为POST方法,提交的数据格式必须是appli ...

  3. Android 工具类 异常处理类CrashHandler

    1.整体分析 1.1.源代码如下,可以直接Copy. public class CrashHandler implements Thread.UncaughtExceptionHandler { pr ...

  4. 7.Mongodb安全性流程

    1.安全性流程 2.超级管理员 为了更安全的访问mongodb,需要访问者提供用户名和密码,于是需要在mongodb中创建用户 采用了角色-用户-数据库的安全管理方式 常用系统角色如下: root:只 ...

  5. python开发记录第一篇

    1. 安装pyCharm,下载地址https://www.jetbrains.com/pycharm/ 2. 注册license,修改windwos系统hosts,文件路径为:C:\Windows\S ...

  6. java前台传参json,后台用map或者实体对象接收

    (一)前台传js对象,里面包含数组,后台用map接收 (1)第一种情况:数组里不包含js对象 var param ={}: param.id=id; param.name=name; var scor ...

  7. VSX-3 VSCT文件

    关于VSPackage中的VSCT,算是VSX开发中比较重要的一个成员. 我这里给出LearnVSXNow!系列文章关于VSCT的链接,除了#14有译文. #14 #18 #25 看完上面几篇文章,也 ...

  8. C#正则表达式引发的CPU跑高问题以及解决方法

    3月23日(周日)下午16:30左右,博客园主站负载均衡中的2台Web服务器CPU玩起了爬楼梯的游戏(见上图),一直爬到了接近100%.发现这个状况后,我们立即将这2台阿里云临时磁盘云服务器从负载均衡 ...

  9. 新浪微博API Oauth2.0 认证

    原文链接: http://rsj217.diandian.com/post/2013-04-17/40050093587 本意是在注销账号前保留之前的一些数据.决定用python 爬取收藏.可是未登录 ...

  10. iphone 8 plus 红色特别版,突然自动关机无法启动

    今天早上我的iphone 8p 突然自己在床上闪动开机图标,闪了半个多小时它就光荣的自动关机了,我尝试了长按开机键,长按home+开机键15秒,通通木有用,它就是没!反!应! 于是找了售后,学到了正确 ...