class MemoryProfiler DEFAULTS={:delay=>10,:string_debug=>false} def self.start(opt={}) opt=DEFAULTS.dup.merge(opt) Thread.newdo prev=Hash.new(0) curr=Hash.new(0) curr_strings=[] delta=Hash.new(0) file=File.open('log/memory_profiler.log','w') loopdo begin GC.start curr.clear curr_strings=[]ifopt[:string_debug] ObjectSpace.each_objectdo|o| curr[o.class]+=1#Marshal.dump(o).size rescue 1 ifopt[:string_debug]ando.class==String curr_strings.pusho end end ifopt[:string_debug] File.open("log/memory_profiler_strings.log.#{Time.now.to_i}",'w')do|f| curr_strings.sort.eachdo|s| f.putss end end curr_strings.clear end delta.clear (curr.keys+delta.keys).uniq.eachdo|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}.eachdo|k,v| file.printf"%+5d: %s (%d) ",v,k.name,curr[k]unlessv==0 end file.flush delta.clear prev.clear prev.updatecurr GC.start rescueException=>err STDERR.puts"** memory_profiler error: #{err}" end sleepopt[:delay] end end end end