c++的内存模型分为五个区:
堆heap:
由new分配的内存空间, 由程序员进行操作, 当不需要的时候调用delete,如果程序员没有将其进行释放, 当程序结束的时候,操作系统会进行回收。
操作不当引发的问题:
内存溢出:申请的大小没能装下应该存储的文件的内容。
内存泄漏:程序员申请的内存空间没有及时的进行释放, 导致内存一直被占用
内存泄露的类型:
1. 常发性内存泄露:发生内存泄漏的代码会被多次执行, 每次执行都会导致一块内存泄漏。
2. 偶发性内存泄漏:发生内存泄漏的代码只在某些特定的环境上才会发生。
3. 一次性内存泄漏:代码只会被执行一次, 有且只有一块内存发生泄漏。
4. 隐式内存泄漏:长时间运行的代码,在运行的过程中不停的分配内存, 只有在结束的时候才进行内存的释放, 这可能会产生内存耗尽的情况。
栈stack
编译器操作的对象,在需要的时候进行分配, 在不需要的时候自动清除。一般存放的是局部变量, 函数参数等。
全局(静态存储区)
全局变量和静态变量分在同一个区里面, 在c中已经被初始化的放在data区, 没有被初始化的被放在bss区。但是在c++里面没有区分了。
常量存储区
也叫rodata区, 存放的是常量, 不允许修改
代码段:
也叫text段,不允许修改, 可以执行。
栈和堆的对比:
栈:程序自动分配释放,由高地址向下生长,分配的速度快,勋饭函数参数值,局部变量。
堆:程序员进行分配使用,由低地址向上生长,使用类似链表,会产生碎片,速度慢。
具体比较:
管理方式:栈为编译器,堆为程序员
生长方向:栈由高地址向下连续分配,堆由低向上不连续分配。
空间大小:栈默认10m,堆的大小受计算机系统中的有效虚拟内存。
存储方式:栈是生存期与函数调用有关,开始入栈,当出栈完成,生命期完成;在堆中用于分配一些生存期与函数调用没有关系的数据,数据的生存期由程序员来控制。
分配方式:栈可以静态分配也可以动态分配,静态分配由编译器完成,动态分配可以调用alloca函数进行在栈上申请空间,用完之后自动释放。堆只能动态分配和手动释放。
分配效率:栈分配由计算机底层提供支持,分配专门的寄存器存放栈地址,压栈由专门的指令进行,效率高。堆的操作由库函数提供,机制复杂,效率较低。
碎片问题:栈不会存在碎片,堆由于频繁的深情释放操作会造成堆内存空间不连续,造成大量的碎片,效率低下。
all