Ruby Spawn或Fork在完成后是否与父进程共享内存?

时间:2013-12-16 20:12:13

标签: ruby fork delayed-job prawn spawn

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

我知道生成的GraphicsMagick进程与父进程共享内存,但在子进程完成后是否将内存返回给系统?如果我在分叉的过程中创建PDF文件,那么在分叉过程完成后,创建PDF文件时使用的内存是否会返回给系统?

1 个答案:

答案 0 :(得分:3)

我继续前进并分叉了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