Be careful when...
- using
.to_sym
,.intern
or:"#{string}"
. Symbols are frozen strings and they are not consumed by Ruby garbage collector. - using the
@@variable
variables, as before, they are not consumed by GC and they stay in memory forever - using
$variable
variables, same as above. YAML.load(File.read('file'))
seems to cause memory leaking under 1.9.3p194Fiber
seems to also cause different kinds of memory leaking- using double quotes, use
''
(single quotes) for strings that do not change like:s='PENDING'
instead ofs="PENDING"
Other hints
- 'thin' web server is actually a big memory consumer (it is not 'thin' anymore . Comparing to webrick, it eats 100% more resources.
How to debug/profile Ruby
There are few tools available, however none of them works with native MRI Ruby (1.9.3p194).
To simply print the current ruby script memory usage in the system, you can use this function:
Code Block |
---|
def get_current_memory_usage `ps -o rss= -p #{Process.pid}`.to_i end |
Also this method will enhance the method above and allow you to print memory footprint
for the block:
Code Block |
---|
def profile_memory(&block) before = get_current_memory_usage file, line, _ = caller[0].split(':') if block_given? instance_eval(&block) puts "[#{file}:#{line}: #{(get_current_memory_usage - before) / 1024} MB (consumed)]" elsehttps://gist.github.com/3912688 before = 0 puts "[#{file}:#{line}: #{(get_current_memory_usage - before) / 1024} MB (all)]" end end |
I also created a Rack middleware that tracks memory usage for every line of code executed. However this middleware
requires to have patched Ruby 1.9.3 (gcdata.patch) to work. (https://gist.github.com/3912688)
Future reading: