class Memory::Sampler
Sample memory allocations.
~~~ ruby sampler = Sampler.capture do
5.times { "foo" }
end ~~~
Attributes
allocated[R]
cache[R]
filter[R]
wrapper[R]
Public Class Methods
new(&filter)
click to toggle source
# File lib/memory/sampler.rb, line 69 def initialize(&filter) @filter = filter @cache = Cache.new @wrapper = Wrapper.new(@cache) @allocated = Array.new end
Public Instance Methods
dump(io = nil)
click to toggle source
# File lib/memory/sampler.rb, line 111 def dump(io = nil) Console.logger.debug(self, "Dumping allocations: #{@allocated.size}") if io packer = @wrapper.packer(io) packer.pack(@allocated) packer.flush else @wrapper.dump(@allocated) end end
load(data)
click to toggle source
# File lib/memory/sampler.rb, line 123 def load(data) allocations = @wrapper.load(data) Console.logger.debug(self, "Loading allocations: #{allocations.size}") @allocated.concat(allocations) end
report()
click to toggle source
# File lib/memory/sampler.rb, line 131 def report report = Report.general report.concat(@allocated) return report end
run() { |&& false| ... }
click to toggle source
Collects object allocation and memory of ruby code inside of passed block.
# File lib/memory/sampler.rb, line 140 def run(&block) start begin # We do this to avoid retaining the result of the block. yield && false ensure stop end end
start()
click to toggle source
# File lib/memory/sampler.rb, line 83 def start GC.disable GC.start @generation = GC.count ObjectSpace.trace_object_allocations_start end
stop()
click to toggle source
# File lib/memory/sampler.rb, line 91 def stop ObjectSpace.trace_object_allocations_stop allocated = track_allocations(@generation) # **WARNING** Do not allocate any new Objects between the call to GC.start and the completion of the retained lookups. It is likely that a new Object would reuse an object_id from a GC'd object. GC.enable 3.times{GC.start} ObjectSpace.each_object do |object| next unless ObjectSpace.allocation_generation(object) == @generation if found = allocated[object.__id__] found.retained = true end end ObjectSpace.trace_object_allocations_clear end
Private Instance Methods
track_allocations(generation)
click to toggle source
Iterates through objects in memory of a given generation. Stores results along with meta data of objects collected.
# File lib/memory/sampler.rb, line 155 def track_allocations(generation) rvalue_size = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE] allocated = Hash.new.compare_by_identity ObjectSpace.each_object do |object| next unless ObjectSpace.allocation_generation(object) == generation file = ObjectSpace.allocation_sourcefile(object) || "(no name)" klass = object.class rescue nil unless Class === klass # attempt to determine the true Class when .class returns something other than a Class klass = Kernel.instance_method(:class).bind(object).call end next if @filter && !@filter.call(klass, file) line = ObjectSpace.allocation_sourceline(object) # we do memsize first to avoid freezing as a side effect and shifting # storage to the new frozen string, this happens on @hash[s] in lookup_string memsize = ObjectSpace.memsize_of(object) class_name = @cache.lookup_class_name(klass) value = (klass == String) ? @cache.lookup_string(object) : nil # compensate for API bug memsize = rvalue_size if memsize > 100_000_000_000 allocation = Allocation.new(@cache, class_name, file, line, memsize, value, false) @allocated << allocation allocated[object.__id__] = allocation end return allocated end