堆和堆栈的回忆是如何协调,实施和分配的

可能重复:
堆和堆栈的回忆是如何处理,实施和分配的?
堆栈,静态和堆在C ++中

在C / C ++中,我们可以将变量,函数,成员函数,类的实例存储在堆栈或堆中。

各自如何实施? 它如何管理(高级别)? gcc是否预先分配了一堆用于栈和堆的内存,然后根据请求进行分配? 原始内存来自RAM吗?

函数可以分配在堆而不是堆栈上吗?

             --Clarification--

我真的在询问关于堆栈和堆栈内存的实现和管理。 在阅读引用的问题后,我没有发现任何解决该问题的内容......感谢链接


我认为对于你的问题,可以很容易地写出关于操作系统的书的至少一些章节。 我建议你阅读Tanenbaum:现代操作系统。

堆栈和堆栈的主要区别在于,每个进程项目和其他每个线程项目是不同的。 最初当程序启动时,它会得到一些最小的堆和一些堆栈段。 堆增长,堆栈是静态的(针对每个线程)。 如果你写了一个不会终止的递归函数(无限递归),你将得到堆栈溢出;)任何函数调用在堆栈段上都有一个堆栈帧,当函数离开时,堆栈被解开并且帧可以被下一个功能。 堆栈是一个连续的线性结构。 在Linux上,您可以通过环境变量配置进程的堆栈段大小。 在windows上(至少在MS Visual C ++中),你可以传递一个链接器标志,其大小为堆栈段。 在编译时分配一些大数组时也可能产生堆栈溢出:

char test[1000000];

堆是一个不同的故事。 当一个进程启动时,堆大小是一些默认值,并且可以从操作系统到操作系统或在该操作系统上使用的配置不同(例如,在Windows上,默认情况下,它是2MB,据我记忆)。 此外,如果您需要更多堆,为变量分配更多空间等,它将会增长。 如果程序没有释放堆内存,它将耗尽它(或堆空间)。 堆实现有不同的数据结构,其中一些是二叉树衍生物,一些不是例如斐波那契堆(forrest of trees)。 你可以阅读一些关于如何编写内存分配器的文章等。 这些数据结构必须进行优化,以便在分配的块需要重新分配时查找堆节点,或者在需要新的堆空间时追加(寻找空闲块)。

32位操作系统上的每个进程都有4GB的虚拟地址空间。 正如你可以想象的那样,所有具有4GB虚拟地址空间的进程都适合所有内存。 操作系统内存按页面组织,在不再需要或过期时交换到HD。 这是寻呼发挥的地方。 所有东西都被映射到页面:一个堆栈或不断增长的堆的进程。 由于它动态增长的堆结构,它可以放置在多个页面上。 这就是为什么堆访问非常昂贵的原因,因为如果页面不在内存中,则会发生页面错误,并且操作系统必须从磁盘加载页面(并且可能会减慢幅度)。 正在执行的线程的堆栈帧位于处理器缓存中,这比RAM快得多。

不同的堆类型是可能的,对于小型对象或堆在多线程环境中非常有效的堆可能会非常快。 Alexandrescu在“Modern C ++ Design”中描述了如何开发小对象分配器和管理小对象的堆。 这个实现在他的Loki C ++库中可用。 一些嵌入式系统提供物理上不同的内存区域,其中不同堆类型可在ontop上实现。 如果你想击败一个编译器,编写一个自己的分配器(堆管理器等)是一项艰巨的工作。

问候,
Ovanes

链接地址: http://www.djcxy.com/p/13789.html

上一篇: How is heap and stack memories mananged, implemented, allocated

下一篇: Difference between 'struct' and 'typedef struct' in C++?