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



我有一个应用程序,它可以处理图像并使用延迟作业在后台创建PDF。使用Process.spawn(通过运行GraphicsMagick进程的subexec-gem)处理图像。然后,我们使用Prawn gem创建一个PDF文件,其中包括这些图像和文本组件。我不相信虾宝石使用叉子或Spawn。我们使用的是Ruby 1.9.3。结果是,在制作了一些PDF文件后,我们的延迟作业处理的内存从大约120MB膨胀到超过800MB。

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

我继续进行PDF创建任务并进行了测试。分叉进程确实在退出后将内存释放回系统,并且我们的延迟作业进程不再失控。我已经附上了代码,以防有人遇到类似的问题。有趣的是,运行Ruby1.9.3+Rails3.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

最新更新