-
-
Save benfyvie/1511115 to your computer and use it in GitHub Desktop.
Tools for debugging memory bloat using Ruby's built in ObjectSpace
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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