为什么堆栈和堆都是内存分配所必需的

时间:2010-06-17 17:24:51

标签: memory dynamic stack heap

我已经搜索了一段时间,但没有确定的答案,为什么必须在堆栈上分配值类型,而引用类型,即动态内存或对象必须驻留在堆上。 为什么不能在堆栈上分配相同的东西?

5 个答案:

答案 0 :(得分:3)

他们可以。实际上,它们并不是因为堆栈通常比堆更稀缺,并且在堆栈上分配引用类型可能会快速耗尽它。此外,如果函数返回在其堆栈上分配的数据,则需要在调用者的部分上复制语义,否则可能会返回将被下一个函数调用覆盖的内容。

值本类型(通常是局部变量)可以使用本机机器指令快速轻松地进入和超出范围。返回时复制值类型的语义是微不足道的,因为大多数适合于机器寄存器。这种情况经常发生,应该尽可能便宜。

答案 1 :(得分:1)

值类型总是存在于堆栈中是不正确的。阅读Jon Skeet关于该主题的文章:

  

<强> Memory in .NET - what goes where

答案 2 :(得分:1)

据我所知, stack 范例(嵌套分配/解除分配)无法处理需要非嵌套对象生存期的某些算法。

正如静态分配范例无法处理递归过程调用一样。 (例如,天然计算斐波那契(n)为f(n-1)+ f(n-2))

我不知道一个简单的算法可以说明这个事实。任何建议将不胜感激: - )

答案 3 :(得分:0)

局部变量在堆栈中分配。如果不是这种情况,则在分配变量的内存时,您将无法将变量指向堆。如果需要,您可以在堆栈中分配内容,只需在本地创建一个足够大的缓冲区并自行管理它。

答案 4 :(得分:0)

当方法退出时,方法放入堆栈的任何内容都将消失。在.net和Java中,如果一个类对象在最后一次引用消失后就消失了,那么它是完全可以接受的(实际上是可取的),但是当一个对象仍然存在对它的引用时消失它将是致命的。一般情况下,编译器在方法创建对象时,不知道在方法退出后是否继续存在对该对象的任何引用。如果没有这样的保证,分配类对象的唯一安全方法是将它们存储在堆上。

顺便说一句,在.net中,可变值类型的一个主要优点是它们可以通过引用传递而不放弃对它们的永久控制。如果类'foo'或其方法具有结构'boz',其中一个foo的方法通过引用方法'bar'传递,则bar或它调用的方法可以做他们想做的任何事情' boz'直到他们返回,但是一旦'bar'返回它所持有的'boz'的任何引用都将消失。与用于类对象的可混合引用相比,这通常会导致更安全和更清晰的语义。