首先须要指出的是。我们通经常使用“堆”和“自由存储”这两个术语来区分两种不同类型的动态分配内存。

1.常量数据:常量数据区域主要用于存储字符串以及其它在编译期就已经知道值的数据。实例化的对象是不能存储在 这 个区域中的。

在程序的整个生存期内。这个区域中的全部数据都是有效的。而且,全部这些数据都是仅仅读的,假设对这些数据进行改动。其结果在C++中是未定义的。

造成这样的后果的部分原因是编译器可能会对常量数据的基本存储格式进行随意优化。

比如,在某个特定的编译器中,可能会将字符串常量保存在重叠对象内以进行优化。

   

2.栈:在栈中存储的是自己主动变量。

自己主动变量在定义的时候被马上构造,而且在自己主动变量作用域结束的时候被马上销毁,因此程序猿无法对已经分配但尚未初始化的栈空间直接进行操作(除非你有意识地使用显示析构函数和布局new语法)。

栈内存的分配通常要比动态内存的分配(堆和自由存储)快非常多,由于每次栈内存的分配仅仅涉及栈指针的自增操作,而无需进行更为复杂的内存管理。

3.自由存储:自由存储时两种动态内存区域之中的一个。它是通过new/delete来分别进行分配/释放。

对象的生存期可能会小于所分配的存储空间的生存期。

也就是说,自由存储区域中的对象在分配内存时并不要求马上进行初始化。而且在销毁对象时。也不要求马上释放内存空间。

在存储空间已经被分配但还没有进入到对象生存期的这段时间内,我们能够通过一个void*类型的指针来訪问和操作这块存储空间。但我们不能訪问对象中不论什么一个非静态的成员或非静态的成员函数。不能去获得他们的地址,或者进行其它的操作。

4.堆:堆是还有一种动态内存区域,它是通过malloc()/free()函数以及这些函数的其它形式来进行分配/释放的。

我们要注意的是,虽然在某个特定的编译器中,默认的全局运算符new和delete可能会用函数malloc()和free()来进行实现,可是堆还是不同于自由存储。在堆中分配的内存不能再自由存储区域中被安全地释放,反之亦然 在堆中分配的内存。能够用于对象的placement new构造过程 和显示的析构过程中。假设是这样的使用方法。那么自由存储区域中关于对象生存期的注意事项也相同适用于堆。

5.全局/静态:在程序启动的时候,这些变量/对象或静态的变量/对象就已经被分配了存储空间,但仅仅有等到程序运行的时候,这些变量/对象才干够进行初始化。

比如:函数中的静态变量仅仅有当程序第一次运行到变量的定义语句时才干被初始化。

对于跨越多个编译单元的全局变量,它们的初始化顺序是未定义的。而且我们在管理全局对象(包含类的静态成员)之间的依赖性的时候要特别小心。通常来说,我们能够通过一个void*指针来对未初始化的对象存储空间进行訪问和操作,但我们不能再对象的生存期之外来使用或者引用非静态的成员变量或成员函数。

指导原则:我们应该优先使用自有存储(new/delete),而且要避免去使用堆(malloc/free)。



C++中的内存区域及其性能特征的更多相关文章

  1. Java虚拟机中Java内存区域

      Java虚拟机所管理的内存将会包括以下几个运行时数据区域. 程序计数器 可以看作是当前线程所执行的字节码的行号指示器. 每一个线程都需要有一个独立的程序计数器. 如果线程正在执行的是一个Java方 ...

  2. 用 Span 对 C# 进程中三大内存区域进行统一访问 ,太厉害了!

    一:背景 1. 讲故事 前段时间写了几篇 C# 漫文,评论留言中有很多朋友多次提到 Span,周末抽空看了下,确实是一个非常

  3. JVM性能优化系列-(1) Java内存区域

    1. Java内存区域 1.1 运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.主要包括:程序计数器.虚拟机栈.本地方法栈.Java堆.方法区(运 ...

  4. jvm的内存区域介绍

    什么是jvm? JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的 ...

  5. JVM的内存区域划分以及垃圾回收机制详解

    在我们写Java代码时,大部分情况下是不用关心你New的对象是否被释放掉,或者什么时候被释放掉.因为JVM中有垃圾自动回收机制.在之前的博客中我们聊过Objective-C中的MRC(手动引用计数)以 ...

  6. 深入了解java虚拟机(JVM) 第三章 内存区域----堆空间

    一.堆的含义 jvm堆的区域主要是用来存放对象的实例,它的空间大小是JVM内存区域中占比重最大的,也是jvm最大的内存管理模块,最重要的是,这个区域是垃圾收集器主要管理的区域,这意味着我们在考虑垃圾回 ...

  7. Linux内存都去哪了:(1)分析memblock在启动过程中对内存的影响

    关键词:memblock.totalram_pages.meminfo.MemTotal.CMA等. 最近在做低成本方案,需要研究一整块RAM都用在哪里了? 最直观的的就是通过/proc/meminf ...

  8. [Spark性能调优] 第四章 : Spark Shuffle 中 JVM 内存使用及配置内幕详情

    本课主题 JVM 內存使用架构剖析 Spark 1.6.x 和 Spark 2.x 的 JVM 剖析 Spark 1.6.x 以前 on Yarn 计算内存使用案例 Spark Unified Mem ...

  9. C/C++中内存区域划分大总结

    C++作为一款C语言的升级版本,具有非常强大的功能.它不但能够支持各种程序设计风格,而且还具有C语言的所有功能.我们在这里为大家介绍的是其中一个比较重要的内容,C和C++内存区域的划分. 一. 在c中 ...

随机推荐

  1. Python中类的特殊变量

    特殊变量 类似__xx,以双下划线开头的实例变量名,就变成了一个私有变量(private),只有内部可以访问,外部不能访问: 类似__xx__,以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变 ...

  2. springmvc上传,下载

    参考: 上传: 如下代码,可将上传内容复制到上传地址 file.transferTo(new File(realPath + File.separator + realName)); http://b ...

  3. jdk 自带的数据库Derby使用

    ij是derby自带的一个功能强大的数据库管理工具,可以进行很多数据库管理的操作,包括创建数据库, 启动/关闭数据库,执行SQL脚本等.完成准备工作后,就可以启动并使用ij工具了. 在cmd中输入如下 ...

  4. SpringBoot Docker Mysql安装,Docker安装Mysql

    SpringBoot Docker Mysql安装,Docker安装Mysql ================================ ©Copyright 蕃薯耀 2018年4月8日 ht ...

  5. twisted 源码分析一:reactor 单例

    一个twisted进程只会有一个reactor反应器,下面我们来看看twisted是怎样实现这个单例反应器的, 路径:twisted\internet\reactor.py 主要代码如下: impor ...

  6. js fetch api

    MDN fatch 返回的对象 type string url string redirected boolean status number ok boolean statusText string ...

  7. Python不支持函数重载

    函数重载与Python: 函数重载的好处就是不用为了不同的参数类型或参数个数,而写多个函数.多个函数用同一个名字,但参数表,即参数的个数和数据类型可以不同.调用的时候,虽然方法名字相同,但根据参数表可 ...

  8. secureCRT修改背景色、字体颜色

    参考: http://blog.csdn.net/jediael_lu/article/details/37729465 http://blog.csdn.net/dagefeijiqumeiguo/ ...

  9. MPD软件工作坊北京站:技术创新与研发效率带来的前沿思考

    在新技术层出不穷.不断迭代的当下,多数企业都在面临技术能力提升,认知升级等问题.面对技术企业的研发环节,为什么你的效率总是提不上来?都在寻找创新的技术领域,为何别人总能抢占先机?提升自己的研发竞争力, ...

  10. html学习_html5 新增标签和属性

    html5 新增标签和属性 1.html发展历程(html有很多版本) 2.快捷键生成不同版本(html4.xhtml.html5) 文档类型不同.字符设定 3.常用新标签 (只有html5才识别的标 ...