2012-11-13 50 views
5

我目前正在学习包括内存在内的低级别arduino内容。我的问题是堆栈和堆栈在内存的另一侧增长,内存不足只会在中间出现某处时发生,或者当其中一个出现在中间时发生。内存不足概念

+7

这就是他们向不同方向发展的全部原因 - 在他们实际发生碰撞之前,你很好。 –

回答

3
  • 没有的概念,“中间”
  • 取决于如何底层操作系统(如果有的话!)管理过程(如果在平台上这样的事情!),堆栈可能具有有限的大小,比“整个内存的其余部分”要小得多
  • 取决于底层操作系统(如果有的话)管理虚拟内存空间的方式(如果存在这样的事情该平台!),堆可能有一个有限的尺寸,小得多的吨韩“整个内存的其余部分”

如果这些限制中的任何一个到位,那么这些区域相互会合的可能性非常小。实际上,他们很可能会更快地耗尽空间,而守护机制将会提高软件例外的相关硬件。

这意味着'内存不足'事件不是一回事。堆栈中有OOM,堆中有OOM。在我的世界中,传统上,与堆栈有关的部分称为StackOverflow :),与堆相关的部分是OutOf [堆]内存。值得注意的是,如果你的平台有一个虚拟内存的概念,那么堆栈很可能仍然是一个单独的空间块,但堆 - 可能是一个稀疏的构造,并且将包含多个分散的空间块,而不是必然以某种上升或下降的方式进行物理排序。在这种情况下,任何遇到任何事情都很难说。 StackOverflow发生在堆栈达到大小限制时,并且OutOfMemory在内存管理器在内存空间中找不到合适的空洞时发生。

如果忽略虚拟内存,并且只谈论“原始硬件”,那么它依赖于......堆栈的真正位置。 IIRC(!),在一些(真正的老)平台上,堆栈被预先分配在位于物理内存开始处的预定义空间中,比如说前十页,并且“增长到最低点”。然后是几页硬件映射表和端口状态映像,然后剩下的尾部就是堆。通过这样的设置,当堆栈指针到达时,StackOverflow上升。这非常“聪明”,因为处理器的状态标志检测零很容易。另外,对于那些旧的处理器来说,到达更低的地址比更高的地址容易得多,所以将经常访问的堆栈放置在较低的地址处是一个很大的优点。

IIRC(!),较新的平台没有这些问题(通常,我们忽略NUMA和类似的东西),以及当前传统的“原始硬件”设置将特殊区域(表,端口映射等)放在空间的起始处,然后是堆,然后是“空闲区域“,则堆栈和堆栈溢出发生在空闲区域消失时,也就是当堆栈满足堆中已有的任何块时。请注意,StackOverflow仍然不意味着OutOfMemory:堆栈可能已经溢出,但堆可能有一些差距,并且仍然可能有很多可用空间!

请注意那些'IIRC'是重要的。我不是Arduino和当前处理器架构方面的专家,而且上面的“历史”细节可能在更新/更老的方面是相当不错的。我给它80%的概率为真。

+0

那流下了一些真光。谢谢 –

1

堆栈具有一定的分配大小,如果超出这个大小,则会发生堆栈缓冲区溢出。

在软件中,当在调用堆栈上使用太多内存时会发生堆栈溢出。调用堆栈包含有限的内存量,通常在程序开始时确定。

来源Wikipedia