【问题标题】:fork () & memory allocation behaviorfork() & 内存分配行为
【发布时间】:2012-10-16 21:53:57
【问题描述】:

我在一个禁用交换且禁用内存过量使用的系统上工作。

假设我的进程当前消耗了 100 MB 内存,而系统可用内存小于 100 MB。

如果我执行 fork() 会失败,因为内核也会尝试为子进程分配 100 MB 空间吗?

我读到 Linux 在分叉时使用写时复制,因此子和父共享所有页面。所以我猜 fork 应该会成功?

假设 fork 成功,假设我在调用 exec() 之前在子进程中有几行代码。因此,父子进程将继续共享文本段,除非子进程触及任何堆内存,否则内存使用量不应有任何变化。这是正确的吗?

Edit: One follow-up question: With swapping/overcommit disabled, can the cumulative VSS 
(Virtual Set Size) of all the processes be more than the available physical memory ?

I tried this out.  VSS of all the processes can be much more than that of the physical 
memory available.

pmap -x output from a process. 

total kB          132588   10744    7192

First number - Virtual Set Size
Second number - Resident Set Size
third number - dirty pages

RSS is < 10% of VSS. This is with swapping and overcommit disabled.

For every shared library loaded I see something like the following..

00007fae83f07000      32      24       0 r-x--  librt-2.12.so
00007fae83f0f000    2044       0       0 -----  librt-2.12.so
00007fae8410e000       8       8       8 rw---  librt-2.12.so

00007fae84312000     252     120       0 r-x--  libevent-2.0.so.5.0.1
00007fae84351000    2048       0       0 -----  libevent-2.0.so.5.0.1
00007fae84551000       8       8       8 rw---  libevent-2.0.so.5.0.1

I guess r-x segment is code and rw- is data. But there is a 2 MB segment 
that is not loaded. I see this 2 MB segment for every single shared library. 
My process loads a lot of shared libraries. That explains the huge difference 
between VSS & RSS.

Any idea what is that 2 MB segment per shared library ? 

When overcommit is disabled, if this process calls fork() will it fail when 
the free memory is less than VSS (132588 Kb) or RSS (10744) ?

【问题讨论】:

  • 您应该提出一个新问题,而不是编辑您的问题以添加更多新问题。
  • 但是 2 MB 段具有 ----- 权限,这意味着它们被映射为防止缓冲区溢出,因此溢出导致段错误而不是读取库代码。此外,我认为只读映射不计入过度使用限制。
  • 谢谢。我不知道这种溢出保护。

标签: linux memory-management linux-kernel fork


【解决方案1】:

是的,如果完全禁用内存过量使用,那么fork 将失败。它将失败,因为如果程序希望写入所有页面,它可能会取消共享所有页面,而严格的过度使用模式不允许这样做。

您可以将fork 替换为vfork,这样就可以了。 vfork 设计为仅在 fork/exec 模型中与 exec 结合使用以启动新进程时使用。

【讨论】:

  • 这种“严格的过量使用模式”是在 Linux 中实际实现的,还是只是理论上的实现?
  • @user4815162342: sysctl -w vm.overcommit_memory=2 vm.overcommit_ratio=100
  • @user4815162342:如果禁用交换,则使用比率 100。如果您有交换,则使用 0 到 50 之间的某个值,因为模式 2 允许使用 (swap + RAM * ratio) 字节。
  • @ZanLynx 另一个问题:在禁用交换/过度提交的情况下,所有进程的累积 VSS(虚拟集大小)能否超过可用物理内存?我问是因为禁用了交换,内核仍然可以进行分页,因此进程的所有地址空间都不需要在内存中。
猜你喜欢
  • 2018-01-29
  • 2017-09-24
  • 2015-04-27
  • 2012-07-29
  • 2015-08-17
  • 2017-11-23
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多