Create a gist now

Instantly share code, notes, and snippets.

Tools for debugging memory bloat using Ruby's built in ObjectSpace
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment