문제

I have an app that processes images and creates PDFs in the background using Delayed Job. The images are being processed using Process.spawn (through the subexec gem) which runs a GraphicsMagick process. We are then creating a PDF file using the Prawn gem, which includes these images and text components. I don't believe that the Prawn gem using Fork or Spawn. We are using Ruby 1.9.3. What happens is that our Delayed Job processes balloons from ~120MB to over 800MB of memory after a few PDF files are made.

I know that the spawned GraphicsMagick processes share memory with the parent process, but is that memory given back to the system after the child processes are finished? If I created the PDF files in a forked process, would the memory used in creating the PDF file be returned to the system after that forked process was completed?

도움이 되었습니까?

해결책

I went ahead and forked the PDF creation tasks and tested it out. The forked processes do indeed release the memory back to the system after they exit, and our Delayed Job processes no longer balloon out of control. I have attached the code in case anyone is facing a similar problem. Interestingly enough, running Ruby 1.9.3 + Rails 3.2.x, we don't need to reconnect to the database in either the forked processes or the parent process. There was much debate about this in other Stackoverflow questions.

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top