Python堆和栈的区别

堆和栈是程序员必须面对的两个概念,在理解这两个概念的时候,需要放到具体的场景中,在不同的场景中堆和栈表示的含义是不同的:

  1. 程序内存布局场景下,堆和栈表示的是两种内存管理方式;
  2. 数据结构场景下,堆和栈表示两种常用的数据结构。

堆和栈其实是操作系统管理进程占用的内存空间的两种管理方式。主要的区别如下:

  1. 管理方式不同:堆和栈是由操作系统自动分配和释放的,无需我们手动操作,堆的申请和释放是由程序员控制,容易出现内存泄漏。
  2. 成长方向不同。堆的增长方向是向上的,内存的地址是从低到高的;栈的增长方向是向下的,内存地址是从高到底的。
  3. 空间的大小不同。每个进程拥有的栈的大小远小于堆的大小。理论上程序员可以申请堆的大小是虚拟内存的大小,进程栈的大小对于64位的windows默认是1MB,对于64位Linux默认位10MB。
  4. 分配的方式不同。堆都是动态分配的,没有静态分配的堆。栈由两种分配方式:静态分配和动态分配,静态分配是由操作系统完成的,例如局部变量的分配。动态分配是通过alloca函数分配的,但是栈的动态分配和堆不同,栈的动态分配是操作系统释放的,不需要手动释放。
  5. 分配效率不同。栈是操作系统自动分配的,在硬件层面支持栈:分配一个专门的寄存器来存放栈的地址,并且由专门的压栈和出栈的指令,决定了高效率的堆栈,堆是由C/C++提供的库函数或运算符应用和管理。实现机制比较复杂,频繁的内存申请容易出现内存碎片,显然堆的效率远低于栈。
  6. 存储内容不同。栈的内容,函数的返回地址,相关参数,局部变量和寄存器内容等。当主函数调用另一个函数时,要保存当前函数的执行断点,需要使用堆栈来实现,首先将main函数的下一条语句的地址压入栈中,即扩展指针寄存器(EIP)的内容,然后是当前栈帧的底部地址,即的内容扩展基指针寄存器(EBP),然后是被调用函数的实参等,一般情况下是从右向左压入堆栈,然后是被调用函数的局部部分。变量,注意静态变量存储在数据段或BSS段中,不会压入堆栈。出栈的顺序正好相反。最后,栈顶指向主函数下一条语句的地址,主程序从这个地址开始执行。堆,一般来说,堆的顶部使用一个字节的空间来存储堆的大小,而堆中的具体存储内容由程序员来填充。

从上面可以看出,与栈相比,由于使用了大量的malloc()/free()或者new/delete,很容易造成大量的内存碎片,并且可能造成切换用户模式和内核模式之间,效率较低。与堆相比,栈在程序中的应用更为广泛。最常见的是函数的调用过程是通过栈来实现的,函数返回地址、EBP、实参和局部变量都存放在栈中。栈虽然有很多优点,但是因为和堆相比没有那么灵活,所以有时候会分配大量的内存空间,主要是使用堆。

无论是堆还是栈,在使用内存时都要防止非法越界。越界导致的非法内存访问可能会破坏程序的堆和栈数据,或者导致程序运行在一个不确定的状态,无法得到预期的结果。导致程序异常崩溃,这些都是我们在编程时处理内存时要注意的问题。

摘录自–>https://www.zkxjob.com/47209

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值