Skip to content

Instantly share code, notes, and snippets.

@pjhyett
Created April 27, 2009 20:00

Revisions

  1. pjhyett created this gist Apr 27, 2009.
    63 changes: 63 additions & 0 deletions memory_profiler.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@
    # simple memory profiler
    # can't remember where I found it (thanks whomever wrote it)

    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