【问题标题】:Does Ruby Spawn or Fork share memory with parent process after completion?Ruby Spawn 或 Fork 完成后是否与父进程共享内存?
【发布时间】:2013-12-16 20:12:12
【问题描述】:

我有一个使用延迟作业在后台处理图像和创建 PDF 的应用程序。正在使用运行 GraphicsMagick 进程的Process.spawn(通过subexec gem)处理图像。然后,我们使用 Prawn gem 创建一个 PDF 文件,其中包括这些图像和文本组件。我不相信 Prawn gem 使用 Fork 或 Spawn。我们使用的是 Ruby 1.9.3。发生的情况是,在制作了几个 PDF 文件后,我们的延迟作业会处理从 ~120MB 到超过 800MB 内存的气球。

我知道生成的 GraphicsMagick 进程与父进程共享内存,但是在子进程完成后,该内存是否会归还给系统?如果我在 fork 进程中创建 PDF 文件,在 fork 进程完成后,用于创建 PDF 文件的内存是否会返回给系统?

【问题讨论】:

  • “是在子进程完成后归还给系统的内存”——显然不是。你有没有把问题提交到 github repo,看到它可能是内存泄漏?
  • 不是您问题的直接答案,但仍然希望有用--Prawn 0.13.0 版修复了几个与内存相关的问题,我们还有另一个专门与嵌入透明 PNG 相关的修复,这应该会大大减少内存占用对于我们将在下周的 0.13.1 中削减的那个功能。 -- 试试master上的代码,看看它是否能解决你的问题。但是请注意,自 Prawn 0.12.0 以来已经发生了很多变化,如果那是您当前使用的版本。 You can find the full CHANGELOG here.
  • 另外,我们不会在 Prawn 中使用 fork 或 spawn,你说得对。
  • 感谢 Gregory...我们确实升级到了 Prawn 0.13,但问题仍然存在。
  • 关于这个主题的文章不错:sitepoint.com/forking-ipc-ruby-part-ii

标签: ruby fork delayed-job prawn spawn


【解决方案1】:

我继续分叉了 PDF 创建任务并对其进行了测试。分叉的进程在退出后确实会将内存释放回系统,并且我们的延迟作业进程不再膨胀失控。我附上了代码,以防有人遇到类似问题。有趣的是,运行 Ruby 1.9.3 + Rails 3.2.x,我们不需要在分叉进程或父进程中重新连接到数据库。在其他 Stackoverflow 问题中对此有很多争论。

def run_in_fork
  read, write = IO.pipe

  pid = fork do
    error = nil
    read.close
    begin
      yield
    rescue => e
      error = e
    end
    Marshal.dump(error, write)
    exit!(0) # skips exit handlers.
  end

  write.close
  result = read.read
  Process.wait(pid)
  raise "Child process failed" if result.empty?
  if exception = Marshal.load(result)
    raise exception
  end
  return true
end


def my_method
  object = MyObject.find.first
  run_in_fork do
    object.long_running_process
  end
  object.reload
end

【讨论】:

    猜你喜欢
    • 2021-12-04
    • 1970-01-01
    • 2012-07-29
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    • 2013-03-06
    • 2012-05-27
    相关资源
    最近更新 更多