【问题标题】:How does the amount of memory for a process get determined?如何确定进程的内存量?
【发布时间】:2011-09-17 18:28:45
【问题描述】:

据我了解,当一个进程正在执行时,它有一些内存可供使用。随着堆栈大小的增加,它从进程的一端构建(忽略堆栈之前的全局变量),而堆从另一端构建。如果你不断地往栈或堆中添加,最终所有的内存都会被这个进程用完。

如何确定进程分配的内存量?我只能想象它取决于一堆不同的变量,但尽可能普遍的反应会很棒。如果需要具体说明,我对用 C++ 编写的 linux 进程感兴趣。

【问题讨论】:

    标签: linux memory process heap-memory stack-memory


    【解决方案1】:

    在您将遇到的大多数平台上,Linux 在启用虚拟内存的情况下运行。这意味着每个进程都有自己的虚拟地址空间,其大小仅由硬件和内核配置它的方式决定。

    例如,在具有“3/1”拆分配置的 x86 架构上,每个用户空间进程都有 3GB 的可用地址空间,其中分配了堆和堆栈。这与系统中有多少物理内存无关。在 x86-64 架构上,每个用户空间进程通常可以使用 128TB 的地址空间。

    物理内存被单独分配以支持该虚拟内存。进程可用的数量取决于系统的配置,但通常它只是“按需”提供 - 主要限制存在多少物理内存和交换文件空间,以及当前有多少用于其他目的.

    【讨论】:

      【解决方案2】:

      堆栈不会神奇地增长。它的大小是静态的,大小是在链接时确定的。因此,当您从堆栈中获取足够的空间时,它会溢出(堆栈溢出;)

      另一方面,堆区域“神奇地”增长。这意味着当堆需要更多内存时,程序会要求操作系统提供更多内存。

      编辑:正如 Mat 在下面指出的那样,堆栈实际上可以在现代操作系统的运行时增加。

      【讨论】:

      • 您的堆栈信息不正确。它可以在运行时增长(至少在 linux 上),并且当它这样做时,它是“神奇的”,因为内核会自动执行此操作而无需进程知道它/必须调用函数。而且堆不会“神奇地”增长,它只会通过来自进程的显式调用(malloc/mmap/sbrk/...)而增长。
      • 是的,你对堆的看法是正确的,它需要进程调用。我确实写过“程序要求”内存......但我不确定堆栈。我用 C 语言编写了一个小测试程序,其中函数调用自身 10M 次并产生了 seg.fault。 (我认为是因为堆栈溢出)。
      • Linux(软硬)有堆栈限制,可以按会话和每个进程进行控制。使用ulimit -s 为您当前的shell 显示它(在bash 中),ulimit -s <somevalue> 设置它(它由孩子继承)。系统范围的限制在/etc/security/limits.conf 中设置。它可以是无限的。进程可以尝试使用setrlimit 增加其允许的堆栈空间。如果您设法将堆栈限制设置为无限制,则在所有 ram 耗尽之前,您的进程不会死亡(并且它不会以巨大的堆栈段开始)。
      • 感谢 Mat 的解释。看来我知道的并不多。
      • 此外,还有一些工作允许非连续堆栈 - 也就是说,当堆栈空间不足时,将分配更多内存,可能不与旧堆栈相邻,并执行将继续在这个新的部分。当您返回超过分配点时,此段将自动释放。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 2010-09-28
      • 2010-09-08
      相关资源
      最近更新 更多