public
Last active — forked from eric/object_diagnostics.rb

Tools for debugging memory bloat using Ruby's built in ObjectSpace

  • Download Gist
object_diagnostics.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
module ObjectDiagnostics
extend self
 
#This is handy when you want to determine what types of objects are contributing to memory bloat
#returns the change in object counts since the last time this method was called
def change_in_object_counts
#this will start all counts at 0 for the initial run
@previous_counts ||= Hash.new(0)
 
#garbage collect before getting the current count so that we are only looking at objects that are causing bloat
ObjectSpace.garbage_collect
 
current_counts = ObjectSpace.count_objects
 
count_differences = {}
current_counts.each do |key, value|
count_differences[key] = ( value - @previous_counts[key] )
end
 
@previous_counts = current_counts
 
count_differences
end
 
def display(method, options = {})
res = format(method, options)
res.each { |l| puts l }
end
def format(method, options = {})
res = calculate(method, options)
case method
when :array_by_content
res.map! { |k, count| "#{count}: #{k.inspect[0..50]}"}
when :string_by_content
res.map! { |k, count| "#{count}: #{k[0..50].inspect}"}
else
res.map! { |k, count| "#{count}: #{k}" }
end
res
end
 
def calculate(method, options = {})
h = Hash.new { |h,k| h[k] = 0 }
mod = Object
p = case method
when :class_by_count
proc { |obj| h[obj.class.to_s] += 1 rescue nil }
when :array_by_length
mod = Array
proc { |obj| h[obj.length] += 1 }
when :array_by_content
mod = Array
proc { |obj| h[obj] += 1 rescue nil }
when :string_by_length
mod = String
proc { |obj| h[obj.length] += 1 }
when :string_by_content
mod = String
proc { |obj| h[obj] += 1 }
else
raise "Unknown method: #{method}"
end
ObjectSpace.each_object(mod, &p)
res = h.sort_by { |(k, v)| v }
if top = options[:top]
res = res[-top ... -1]
end
res
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.