Skip to content

Instantly share code, notes, and snippets.

@djromero
Forked from JoshCheek/most_allocated_objects.rb
Created October 16, 2022 09:31
Show Gist options
  • Save djromero/3313af2a615a056ae2ee0f3d1bcffe0c to your computer and use it in GitHub Desktop.
Save djromero/3313af2a615a056ae2ee0f3d1bcffe0c to your computer and use it in GitHub Desktop.
Finding locations of most allocated objects
require 'objspace'
def self.show_allocations(&block)
_ = ObjectSpace.trace_object_allocations &block
ObjectSpace
.each_object
.to_a
.filter_map do |obj|
file = ObjectSpace.allocation_sourcefile obj
line = ObjectSpace.allocation_sourceline obj
file && ["#{file}##{line}", obj.class.inspect] # objects created outside of the allocation tracing
end
.tally
.sort_by { -_1.last }
.map { |(loc, klass), tally| [tally, klass, loc] }
end
def self.format_allocations(limit=10, allocations)
rows = allocations.take(limit).each { _1[0] = _1[0].to_s.gsub(/(?<=.)(?=.{3}+$)/, ",") }
width_n, width_class, width_loc = rows.transpose.map { _1.map(&:to_s).map(&:size).max }
format = "%#{width_n}s | %#{width_class}s | %-#{width_loc}s\n"
rows.map { format % _1 }.join("")
end
require 'json'
puts format_allocations show_allocations {
[ 10_000.times.map { "a" },
5_000.times.map { "b" },
JSON.parse('{ "c": 123, "d": true, "e": "f" }'),
]
}
# >> 10,000 | String | program.rb#27
# >> 5,000 | String | program.rb#28
# >> 4 | String | /Users/josh/.gem/ruby/3.0.2/gems/json-2.6.1/lib/json/common.rb#216
# >> 2 | Array | program.rb#27
# >> 2 | Hash | /Users/josh/.gem/ruby/3.0.2/gems/json-2.6.1/lib/json/common.rb#216
# >> 2 | Hash | /Users/josh/.gem/ruby/3.0.2/gems/json-2.6.1/lib/json/common.rb#127
# >> 1 | JSON::Ext::Parser | /Users/josh/.gem/ruby/3.0.2/gems/json-2.6.1/lib/json/common.rb#216
# >> 1 | Hash | /Users/josh/.gem/ruby/3.0.2/gems/json-2.6.1/lib/json/common.rb#215
# >> 1 | Enumerator | program.rb#27
# >> 1 | String | program.rb#29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment