class RSpec::Memory::Trace

Attributes

allocated[R]
ignored[R]
retained[R]
total[R]

Public Class Methods

capture(*args, &block) click to toggle source
# File lib/rspec/memory/trace.rb, line 49
def self.capture(*args, &block)
        self.new(*args).tap do |trace|
                trace.capture(&block)
        end
end
new(klasses) click to toggle source
# File lib/rspec/memory/trace.rb, line 62
def initialize(klasses)
        @klasses = klasses
        
        @allocated = Allocation.default_hash
        @retained = Allocation.default_hash
        
        @ignored = Allocation.default_hash
        
        @total = Allocation.new(0, 0)
end
supported?() click to toggle source
# File lib/rspec/memory/trace.rb, line 41
def self.supported?
        # There are issues on truffleruby-1.0.0rc9
        return false if RUBY_ENGINE == "truffleruby"
        
        ObjectSpace.respond_to?(:trace_object_allocations)
end

Public Instance Methods

capture(&block) click to toggle source
# File lib/rspec/memory/trace.rb, line 96
def capture(&block)
        GC.start
        
        begin
                GC.disable
                
                generation = GC.count
                ObjectSpace.trace_object_allocations(&block)
                
                allocated = current_objects(generation)
        ensure
                GC.enable
        end
        
        GC.start
        retained = current_objects(generation)
        
        # All allocated objects, including those freed in the last GC:
        allocated.each do |object|
                if klass = find_base(object)
                        @allocated[klass] << object
                else
                        # If the user specified classes, but we can't pin this allocation to a specific class, we issue a warning.
                        if @klasses.any?
                                warn "Ignoring allocation of #{object.class} at #{ObjectSpace.allocation_sourcefile(object)}:#{ObjectSpace.allocation_sourceline(object)}"
                        end
                        
                        @ignored[object.class] << object
                end
                
                @total << object
        end
        
        # Retained objects are still alive after a final GC:
        retained.each do |object|
                if klass = find_base(object)
                        @retained[klass] << object
                end
        end
end
current_objects(generation) click to toggle source
# File lib/rspec/memory/trace.rb, line 80
def current_objects(generation)
        allocations = []
        
        ObjectSpace.each_object do |object|
                if ObjectSpace.allocation_generation(object) == generation
                        allocations << object
                end
        end
        
        return allocations
end
find_base(object) click to toggle source
# File lib/rspec/memory/trace.rb, line 92
def find_base(object)
        @klasses.find{|klass| object.is_a? klass}
end