Skip to content

Instantly share code, notes, and snippets.

@olegkovalenko
Forked from arp/allocation_map.rb
Created May 31, 2013 19:09
Show Gist options
  • Save olegkovalenko/5687214 to your computer and use it in GitHub Desktop.
Save olegkovalenko/5687214 to your computer and use it in GitHub Desktop.
# Ruby has #source_location method that returns code location where a method was declared.
# What Ruby lacks is alike functionality that could show where an object was created.
# Below is a very rough solution that may help with tracing object allocations
# by storing the first entry in the caller list during object initialization phase.
# It doesn't work for built-in classes like Fixnum and for classes that don't invoke #initialize()
# like the ones derived from ActiveRecord::Base, but can be potentially tailored to address
# at least the latter case by overriding ActiveRecord::Base.new in addition to overriding #initialize()
class BasicObject
attr_reader :allocated_at
def initialize_with_allocated_at(*options)
unless @allocated_at
@allocated_at = caller.first
return initialize_without_allocated_at(*options)
end
end
def self.enable_allocated_at
self.send :alias_method, :initialize_without_allocated_at, :initialize
self.send :alias_method, :initialize, :initialize_with_allocated_at
end
end
ObjectSpace.each_object(Class) do |klass|
klass.enable_allocated_at
end
class Object
# Call this method to get a hash where
# keys are strings representing locations in the source code
# and values are objects allocated at these locations
#
# Example:
# allocation_map(Person) # only show places where Person.new was called
# or
# allocation_map() # beware, this may return A LOT of objects
#
def allocation_map(*each_object_options)
ObjectSpace.each_object(*each_object_options).reduce({}) { |hash, object|
hash[object.allocated_at] ||= []
hash[object.allocated_at] << object if object.respond_to?(:allocated_at)
hash
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment