C++中的内存区域及其性能特征

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

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

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

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

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

   

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

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

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

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

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

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

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

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

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

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

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

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

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


上一篇:SpringCloud微服务负载均衡与网关


下一篇:一起学习android使用一个回调函数onCreateDialog实现负载对话(23)