内存溢出概念

5

我目前正在学习与内存有关的低级Arduino技术。我的问题是,由于堆和栈在内存的相反侧增长,所以如果两者在某个地方相遇,是否会发生内存不足,或者当它们中的一个到达中间时就会发生内存不足。


7
这就是它们生长方向不同的全部原因——在它们真正碰撞之前,你都是安全的。 - Sam Dufel
2个回答

3
  • 没有"中间"的概念。
  • 根据底层操作系统(如果有的话!)如何管理进程(如果平台上有这种东西!),堆栈的大小可能会受到限制,远小于"整个内存的其余部分"。
  • 根据底层操作系统(如果有的话!)如何管理虚拟内存空间(如果平台上有这样的东西!),堆可能会具有有限的大小,比"整个内存的其余部分"小得多。

如果存在以上任何限制,则这些区域相遇的可能性极小。实际上,它们很可能很快就会耗尽空间,保护机制将引发相关的硬件或软件异常。

这意味着'内存不足'事件不是一件事情。在我的世界里,传统上与堆栈相关的称为StackOverflow :),与堆相关的称为OutOf[Heap]Memory。

值得注意的是,如果您的平台具有虚拟内存的概念,则栈很可能仍然是一个单一的空间块,但堆-可能是一个稀疏的构造,并由多个分散的空间块组成,不一定按某种升序或降序的方式物理排序。 在这种情况下,很难谈论任何东西相遇。当栈达到大小限制时,StackOverflow发生,当内存管理器无法在内存空间中找到合适的空闲空间时,便会发生OutOfMemory。

如果忽略虚拟内存,并且只谈论'原始硬件',则它取决于..栈实际上位于哪里。我IRC(!),在某些(真的很老的)平台上,堆栈预先分配在物理内存开始处的一些预定义空间中,比如前十页,并向下增长。然后是几页硬件映射表和端口状态图像,然后剩下的尾部就是堆。 采用这种设置时,当堆栈指针达到零时,StackOverflow就会上升。这样做相当'智能',因为使用处理器状态标志易于检测零。此外,对于那些旧处理器来说,到达低地址比高地址更容易,因此将经常访问的堆栈放在较低地址是一个大的优点。

我IRC(!),新平台通常不会遇到这些问题(通常,让我们忽略NUMA和类似的事情),并且当前传统的“原始硬件”设置将特殊区域(表,端口映射等)放在空间的开始处,然后是堆, 然后是'空闲区域',然后是栈,当空闲区域消失时即栈遇到堆中的任何块时,就会发生StackOverflow。请注意,StackOverflow仍不意味着OutOfMemory:堆可能已经溢出,但堆仍可能有一些间隙,仍然可能有大量的空闲空间!

请注意,这些“IIRC”很重要。我不是Arduino和当前处理器体系结构的专家,而且上面的“历史”问题可能相当偏离真实情况。我认为它的真实性有80%。


1

栈有一定的分配大小,如果超出该大小,将会发生栈缓冲区溢出。

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

来源 维基百科


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接