程序设计中,堆和栈比较重要。栈存取速度大于堆,而且编译器可以修改栈大小,这个值可以随意设置吗?

如题所述

第1个回答  2018-03-21

学习电脑编程多年了,在程序设计方面也算有一番见解,希望这些经验能对题主有所帮助。

    实际上,当我们不考虑缓存时,堆和堆栈的速度是绝对没有差别的。当我们考虑缓存时,因为堆栈是当前代码段中最常被访问的内存,它在缓存上的概率几乎是100%。换句话说,不会有缓存遗漏(不要使用异常,因为我们讨论的是一般情况)。一般来说,缓存遗漏会出现,虽然缓存遗漏可以通过适当的编码方法来减少,但是一般来说,无法与堆栈进行比较。这就是堆栈快速和堆缓慢的原因。如果您已经知道前面的语句,那么您希望通过扩展堆栈来提高程序的性能,这基本上是无用的,因为缓存是固定在指定的机器上的。

    您提到的缺省的1M堆栈应该引用调用堆栈。该堆栈用于存储由函数调用传递的参数(不是所有参数都通过堆栈传递)、堆栈指针、返回地址、寄存器备份和每个层函数的局部变量。大多数情况都是足够的,如果你用光了它们,就会出现非法访问等错误。您可能会使用一个1米的例子:一些被调用的函数应用于一个大型的局部变量,例如堆栈上的一个大数组。然后是递归调用,在递归层之后很容易使用1 m。所以我不想递归地使用这个。

    现在堆栈通常默认为8M,对吧?事实上,如果你不滥用递归,或者alloca / vla,大多数时候,就足够了。即使它不超过内核限制,通常也不适合驱动大型的,或者它会影响并发进程的数量。并且过程启动时间也应该稍微减少。当然,如果是专用的服务器系统,问题就不严重了。

第2个回答  2018-03-21

也许你会觉得学电脑多年,依然感觉电脑这趟水很深,你会遇到很多问题,这就需要你自己去克服了,慢慢来,相信你会成为电脑高手的。


我觉得x86上面的堆栈内存,主栈是由SS和SP访问,在32位保护模式下,SS登记是一段选择器选择器是一个数字,通过IDT(局部描述符表)或GDT(全局描述符表)选择一个段描述符包含细分市场的规模和范围信息描述。

这就是我所知道的和cpu有关的,段的大小上限为4GB(即使你的电脑没有4G的内存)。之所以说栈主要是用ss和sp访问是因为其他寻址方式访问栈段是完全可以的,不过push和pull指令压栈和出栈看起来要简单一点,至于有没有速度优势?

我猜应该没有吧,否则处理器的构架设计师会被吐槽的。至于为什么操作系统会限制栈段的大小(一般情况下,x86的操作系统控制段大小应该位是通过描述符控制的),因为程序使用栈的空间都不会使用太大的栈空间,因为std调用协议是这样的:(我瞎编的,不要当真) 函数调用时,右边的参数先入栈。





于是每次调用其他函数时,先push各个参数,然后call,call指令会只压入eip或者一起压入cs:eip,取决于短跳转还是长跳转。

然后进入函数之后,函数开始声明局部变量,这些变量就被压栈,紧跟在eip之后,你都用不了多大的栈,多多的分配给你不是浪费吗。并没有资料显示栈会比堆快,除了申请的时候慢了一点之外。当然可能会和高速缓存命中率有关。

堆栈和堆都是内存的组成部分

没有更快的论证,有些书说堆栈比堆效率高。这是由于访问算法和堆栈访问效率的差异。不同之处在于堆栈是由编译器分配的。例如,如果您定义了一个局部变量,它会自动分配给堆栈,而这个堆是程序员分配的。在C语言中,外显记忆是通过malloc分配存储数据。

相似回答