# Setup any specified hard limit on the virtual size of the process if defined?(HARD_MEMORY_LIMIT) and defined?(PhusionPassenger) and Process.const_defined?(:RLIMIT_AS) Process.setrlimit Process::RLIMIT_AS, HARD_MEMORY_LIMIT*1024*1024, Process::RLIM_INFINITY end # If we're running under passenger and a soft memory limit is # configured then setup some rack middleware to police the limit if defined?(SOFT_MEMORY_LIMIT) and defined?(PhusionPassenger) # Define some rack middleware to police the soft memory limit class MemoryLimit def initialize(app) @app = app end def call(env) # Process this requst status, headers, body = @app.call(env) # Restart if we've hit our memory limit if resident_size > SOFT_MEMORY_LIMIT Process.kill("USR1", Process.pid) end # Return the result of this request [status, headers, body] end private def resident_size # Read statm to get process sizes. Format is # Size RSS Shared Text Lib Data fields = File.open("/proc/self/statm") do |file| fields = file.gets.split(" ") end # Return resident size in megabytes return fields[1].to_i / 256 end end # Install the memory limit checker Rails.configuration.middleware.use MemoryLimit end