区别:
- 管理方式不同
程序运行时,栈是由操作系统自动分配管理,无需程序员人工控制,包括函数的参数值,返回值,局部变量等,而堆空间的盛情,释放都是由程序员人工控制,也因此容易产生内存泄露。 - 空间大小不同
栈是向低地址扩展,是一块连续的内存区域。即栈顶的地址和栈的最大容量是系统预先规定好的,当申请的空间超过栈的剩余空间时,将出现栈溢出错误。而堆是高地址扩展,是不连续的内存区域。因为系统是用链表来存储空闲内存地址的。且链表的遍历方向是由低地址向高地址扩展。 - 产生碎片不同
对于堆来说,频繁的malloc/free (new/delete) 势必会造成内存空间的不连续,从而造成大量的内存碎片,程序的运行效率降低。而对于栈来说,分配的一定是连续的内存空间。 - 分配方式不同
堆都是程序中由malloc/new
函数动态 申请分配,有free/delete
函数释放的;而栈的分配和释放是由操作系统完成的。而栈的动态分配可有alloc()
函数手动完成,但一般都无需手动操作,而是交给编译器自动进行申请和释放的。 - 分配效率不同
堆的内存分配效率比栈要低得多。因为栈是有操作系统提供的,会在底层堆栈提供支持,分配专门的寄存器存放栈的地址,包括压栈出栈也都有专门的指令执行,所以执行效率很高。而堆则是有C函数提供支持,它的机制相对复杂,例如分配一块内存,库函数会按照一定的算法在对内存空间中搜索可用的足够大的内存空间,如果没有足够大的连续空间,则需要操作系统来重新整理堆内存,这样才有机会分到足够大小的空间,然后才返回。
堆栈的区别要从虚拟地址空间说起,在虚拟地址空间的布局中,有(.text)段,(.data)段,(.bss)段,堆,栈,命令行参数,环境变量等,
从图中可以看出,对战时两亏完全不同的内存。
-
栈内存是有操作系统分配和释放的,同时是以函数为单位进行分配的,函数栈帧,局部变量,形参变量都是在存放栈内存上的;
而堆内存是有程序员自己管理的,如果操作不当,会造成内存泄漏,栈内存由系统管理,所以不会产生内存泄漏。
-
栈内存是由高地址向低地址分配的连续内存块,栈的大小一般是2M或者10M;
堆内存是由低地址想搞地址分配的非连续内存块,这是由于系统使用链表来存储空闲的内存地址;
堆的大小则首先于计算机系统中有效的虚拟内存,32位Linux系统中堆内存可达2.9G 空间。
-
栈内存的分配释放速度快,效率高,原因是其分配的内存是连续的;而堆内存的分配释放相对于栈内存小效率低一些,原因是其内存不一定是连续的,容易产生碎片,但是其灵活性好。
来源于网络