diff options
-rw-r--r-- | lib/memory_profiler.rb | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/memory_profiler.rb b/lib/memory_profiler.rb new file mode 100644 index 000000000..8fecc3138 --- /dev/null +++ b/lib/memory_profiler.rb @@ -0,0 +1,63 @@ +# Taken from +# http://scottstuff.net/blog/2006/08/17/memory-leak-profiling-with-rails + +class MemoryProfiler + DEFAULTS = {:delay => 10, :string_debug => false} + + def self.start(opt={}) + opt = DEFAULTS.dup.merge(opt) + + Thread.new do + prev = Hash.new(0) + curr = Hash.new(0) + curr_strings = [] + delta = Hash.new(0) + + file = File.open('log/memory_profiler.log','w') + + loop do + begin + GC.start + curr.clear + + curr_strings = [] if opt[:string_debug] + + ObjectSpace.each_object do |o| + curr[o.class] += 1 #Marshal.dump(o).size rescue 1 + if opt[:string_debug] and o.class == String + curr_strings.push o + end + end + + if opt[:string_debug] + File.open("log/memory_profiler_strings.log.#{Time.now.to_i}",'w') do |f| + curr_strings.sort.each do |s| + f.puts s + end + end + curr_strings.clear + end + + delta.clear + (curr.keys + delta.keys).uniq.each do |k,v| + delta[k] = curr[k]-prev[k] + end + + file.puts "Top 20" + delta.sort_by { |k,v| -v.abs }[0..19].sort_by { |k,v| -v}.each do |k,v| + file.printf "%+5d: %s (%d)\n", v, k.name, curr[k] unless v == 0 + end + file.flush + + delta.clear + prev.clear + prev.update curr + GC.start + rescue Exception => err + STDERR.puts "** memory_profiler error: #{err}" + end + sleep opt[:delay] + end + end + end +end |