Memory management 程序的内存布局是否依赖于地址绑定技术?

Memory management 程序的内存布局是否依赖于地址绑定技术?,memory-management,operating-system,heap-memory,memory-layout,stack-memory,Memory Management,Operating System,Heap Memory,Memory Layout,Stack Memory,我了解到,通过运行时地址绑定,程序可以在物理内存中不连续地分配帧。此外,如前所述和所述,逻辑地址空间中程序的每个段都是连续的,但并非所有段都并排放置在一起。文本、数据、BSS和堆段放在一起,但堆栈段不放在一起。换句话说,在逻辑地址空间中,堆和堆栈段之间(程序中断和堆栈顶部之间)存在未映射到物理地址空间中任何帧的页,因此这意味着在运行时地址绑定的情况下,逻辑地址空间是不连续的 但是,在编译时或加载时绑定的情况下,内存布局如何?既然逻辑地址空间不是抽象地址空间,而是实际的物理地址空间,那么程序是如

我了解到,通过运行时地址绑定,程序可以在物理内存中不连续地分配帧。此外,如前所述和所述,逻辑地址空间中程序的每个段都是连续的,但并非所有段都并排放置在一起。文本、数据、BSS和堆段放在一起,但堆栈段不放在一起。换句话说,在逻辑地址空间中,堆和堆栈段之间(程序中断和堆栈顶部之间)存在未映射到物理地址空间中任何帧的页,因此这意味着在运行时地址绑定的情况下,逻辑地址空间是不连续的


但是,在编译时或加载时绑定的情况下,内存布局如何?既然逻辑地址空间不是抽象地址空间,而是实际的物理地址空间,那么程序是如何在物理内存中布局的呢?更具体地说,堆栈段如何放置在程序的物理地址空间中?它是与其余的段放在一起,还是像运行时绑定一样单独放置?

为了回答您的问题,我首先要解释一下现代操作系统中的
堆栈和
堆分配

堆栈顾名思义就是持续内存分配,cpu使用
push
pop
命令在堆栈顶部添加/删除数据。我假设您已经知道堆栈是如何工作的。进程存储—堆栈上的返回地址、函数参数和局部变量。每次调用函数时,都会推送更多的数据(如果没有数据弹出,最终可能导致堆栈溢出-无限递归?)。当程序加载到内存中时,堆栈大小是固定的。大多数编程语言都允许您在编译期间决定堆栈大小。如果没有,他们将决定违约。在Linux上,最大堆栈大小(硬限制)受
ulimit
的限制。您可以通过
ulimit-s
检查和设置大小

但是,堆空间在*nix系统中没有上限(取决于,使用
ulimit-v
确认),每个程序都以默认/设置的堆量开始,并且可以根据需要增加堆空间。进程中的堆空间实际上是两个链表,
free
used
块。每当需要从堆中分配内存时,一个或多个空闲块被组合成一个更大的块,并作为单个块分配给已用列表。释放意味着将一个块从已用列表中移除到空闲列表中。释放块后,堆可以有外部碎片。现在,如果空闲块的数量不能包含整个数据,进程将从操作系统请求更多内存,通常较新的块是从更高的地址分配的。因此,我们展示了堆增长的向上方向图。我的意思是-堆不会在更高的方向上连续分配内存

现在回答你的问题

使用编译时或加载时地址绑定,堆栈和 放在程序物理地址空间中的堆段

固定堆栈在编译时分配,带有一些堆内存。如何放置已在上面解释过

堆和堆栈之间的空间是否为程序保留 或者该操作系统是否可用于其他程序

是的,它是为节目保留的。然而,进程可以请求更多内存以在其堆中添加空闲块。它不同于共享自己的堆

注:由于问题涉及面很广,这里可以涵盖很多主题。其中一些是垃圾收集、块选择、共享内存等。我将很快在这里添加引用

参考资料:-