堆和栈的区别
1、管理方式:栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;
2、生长方向:堆的生长方向向上,内存地址由低到高,是不连续的内存区域;栈的生长方向向下,内存地址由高到低,是连续的内存区域。
3、空间大小:理论上,程序员可申请的堆大小为虚拟内存的大小,Window进程栈的大小默认 为1MB,Linux下为10MB;
4、存储内容:栈存放的内容,函数返回地址、相关参数、局部变量和寄存器内容等。当主函数调用另外一个函数的时候,要对当前函数执行断点进行保存,需要使用栈来实现,首先入栈的是主函数下一条语句的地址,即扩展指针寄存器的内容(EIP),然后是当前栈帧的底部地址,即扩展基址指针寄存器内容(EBP),再然后是被调函数的实参等,一般情况下是按照从右向左的顺序入栈,之后是被调函数的局部变量,注意静态变量是存放在数据段或者BSS段,是不入栈的。出栈的顺序正好相反,最终栈顶指向主函数下一条语句的地址,主程序又从该地址开始执行。堆,一般情况堆顶使用一个字节的空间来存放堆的大小,而堆中具体存放内容是由程序员来填充的。
5、分配方式:栈可静态分配或动态分配。静态分配有编译器完成,如局部变量的分配。动态分配有alloca函数在栈上申请空间,用完后自动释放不需要调动free函数。堆只能动态分配且手工释放。
6、分配效率:栈由计算机底层提供支持:分配专门的寄存器存放栈地址,压栈出栈由专门的指令执行,因此效率较高。堆由函数库提供,机制复杂,效率比栈低得多。
7、碎片问题:栈不会存在碎片问题。频繁申请释放空间会造成堆内存空间的不连续,从而造成大量碎片,是程序效率降低。