操作系统如何限制堆栈和堆的大小?


21

注意:如果您需要考虑特定的操作系统才能回答问题,请考虑使用Linux。

每当我运行一个程序时,都将为其分配一个虚拟内存空间,其中有一个用于堆栈的区域,一个用于堆栈的区域。

问题1:堆栈和堆是否有静态大小限制(例如,每个大小为2 GB),还是该限制是动态的,根据程序执行期间的内存分配而变化(即,总共4 GB供用户使用)两者兼而有之,因此,如果程序仅使用堆栈,那么它将能够具有4 GB的堆栈)?

问题2:如何定义限制?它是总可用RAM内存吗?

问题3:文本(代码)和数据部分如何处理,如何限制它们?


Answers:


23

有两个不同的内存限制。虚拟内存限制和物理内存限制。

虚拟内存

虚拟内存受可用地址空间的大小和布局限制。通常,最开始是可执行代码和静态数据以及过去增加堆的内容,而最后是内核保留的区域,然后是共享库和堆栈(在大多数平台上会减少)。这样就给堆和栈提供了可用的增长空间,而其他区域在进程启动时是已知的并已修复。

可用虚拟内存最初并未标记为可用,但在分配期间被标记为可用。尽管堆可以增长到所有可用内存,但是大多数系统不会自动增长堆栈。IIRC堆栈的默认限制在Linux上为8MiB,在Windows上为1MiB,并且可以在两个系统上更改。虚拟内存还包含任何内存映射文件和硬件。

不能(任意)自动增长堆栈的原因之一是,多线程程序需要为每个线程使用单独的堆栈,因此它们最终会互相干扰。

在32位平台上,虚拟内存总量为4GiB,Linux和Windows通常都为内核保留最后的1GiB,最多为您提供3GiB的地址空间。有一个特殊的Linux版本,它不保留任何东西给您完整的4GiB。这对于罕见的大型数据库很有用,因为最后一个1GiB节省了一天的时间,但是对于常规使用,由于额外的页表重新加载,它的速度稍慢一些。

在64位平台上,虚拟内存为64EiB,您无需考虑。

物理内存

物理内存通常仅在进程需要访问时才由操作系统分配。进程使用多少物理内存是非常模糊的数字,因为进程之间共享一些内存(代码,共享库和任何其他映射的文件),文件中的数据按需加载到内存中,而当内存不足时会被丢弃。可以交换“匿名”内存(没有文件支持的内存)。

在Linux上,当物理内存用尽时会发生什么情况取决于vm.overcommit_memory系统设置。默认为过量使用。当您要求系统分配内存时,它会为您分配一些内存,但只会分配虚拟内存。当您实际访问内存时,它将尝试使用一些物理内存,丢弃可重新读取的数据或根据需要交换数据。如果发现它无法释放任何东西,它将简单地将进程从存在中移除(没有办法做出反应,因为这种反应可能需要更多的内存,并且会导致无限循环)。

这就是进程在Android(也是Linux)上死亡的方式。逻辑通过使用哪个逻辑从哪个进程中删除来进行了改进,该逻辑基于该进程正在执行的操作以及该进程的存在时间。比android进程简单地停止执行任何操作,而是坐在后台,当需要新的内存时,“内存不足杀手”将杀死它们。


9

我认为按照内存的使用顺序来回答这个问题比较容易。

问题3:文本(代码)和数据部分如何处理? 文本和数据由编译器准备。编译器的要求是确保它们可访问并将它们打包在地址空间的下部。可访问的地址空间将受到硬件的限制,例如,如果指令指针寄存器为32位,则文本地址空间将为4 GiB。

问题2:如何定义限制?它是总可用RAM内存吗? 在文本和数据之后,上方的区域是堆。使用虚拟内存,堆实际上可以增长接近最大地址空间的程度。

问题1:堆栈和堆是否有静态大小限制(例如,每个限制为2 GB),还是该限制是动态的,根据程序执行期间的内存分配而变化(即,供用户使用的总大小为4 GB)两者兼而有之,因此,如果程序仅使用堆栈,那么它将能够具有4 GB的堆栈)? 进程地址空间中的最后一段是堆栈。该堆栈采用了地址空间的结尾部分,它从末端开始,生长下来

由于堆长大而栈长大,它们基本上相互限制。另外,由于两种类型的段都是可写的,所以其中一个段越过边界并不总是违反规则的,因此您可能会有缓冲区或堆栈溢出。现在有阻止它们发生的机制。

开始的每个进程对堆(堆栈)都有设置的限制。可以在运行时更改此限制(使用brk()/ sbrk())。基本上,当进程需要更多的堆空间并且已用完分配的空间时,标准库将向操作系统发出调用。操作系统将分配一个页面,该页面通常由用户库管理以供程序使用。即,如果程序需要1 KiB,则OS将为程序提供额外的4 KiB,而库将为程序提供1 KiB,并在程序下次请求更多信息时剩余3 KiB供使用。

大多数情况下,布局将是文本,数据,堆(向上增长),未分配的空间,最后是堆栈(向下增长)。它们都共享相同的地址空间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.