【问题标题】:Does all memory flagged as copy-on-write get copied after a single change to one piece of the data?在对一条数据进行一次更改后,是否会复制所有标记为写时复制的内存?
【发布时间】:2011-06-11 23:30:21
【问题描述】:

我的问题可能是措辞不佳,源于我对内存管理的业余理解。

我担心的是:我有一个 Perl 脚本,它会分叉很多次。正如我从 perldoc 中的 fork 页面所了解的那样,正在实施写时复制。然后每个孩子调用system(),再次分叉,调用外部程序。来自外部程序的数据被读回子程序,并作为可存储文件转储,以便在所有子程序退出后由父程序获取和处理。

让我担心的是我对这种情况的感知波动。考虑一下我在脑海中看到的最坏情况: 对于每个孩子,只要有新数据到达,整个写时复制内存就会被复制。如果是这种情况,我会在创建几个 fork 后很快遇到内存问题。

或者,写时复制是否只复制包含所需数据的最小内存块?那么这个内存量是什么?它的大小是如何设置的?

我不确定我所询问的具体内容是依赖于语言还是依赖于某些较低级别的过程。

【问题讨论】:

    标签: perl memory-management fork copy-on-write


    【解决方案1】:

    是的,分叉会增加你的内存占用。如果这是一个问题,请使用Parallel::ProcManagerForks::Super 之类的模块来限制活动后台进程的数量。当您的进程受 CPU 限制、I/O 限制或可能过度使用您机器上的任何其他有限资源时,限制活动分叉的数量也是一个好主意。

    use Forks::Super MAX_PROC => 10, ON_BUSY => block;
    
    ...
    $pid = fork();        # blocks if there are already 10 child processes
    ...                   # unblocks when one of the children finishes
    

    【讨论】:

    • 谢谢。 Forks::Super 看起来很棒。
    • 不过要小心 - 通过阻止新进程的创建可能会造成死锁,例如,如果父进程等待子进程(由于进程限制而永远不会启动) .
    • 如果子进程还没有启动,那么它没有进程ID,你不能等待它。只要现有的子进程最终会完成,就不会导致死锁。
    • 我应该更清楚一点:如果子进程需要为父进程做一些工作才能继续,而子进程永远不会启动,您可能会卡住。
    【解决方案2】:

    内存按页面组织,通常每个 4K(这可以设置为不同的值,并且是特定于硬件的,但这是具有标准操作系统的英特尔平台上的标准)。当子进程写入写时复制页面时,它将被复制。

    【讨论】:

      猜你喜欢
      • 2019-09-05
      • 1970-01-01
      • 2014-10-24
      • 2012-01-20
      • 2020-03-30
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      相关资源
      最近更新 更多