Class: Memory::Sampler

Inherits:
Object
  • Object
show all
Defined in:
lib/memory/sampler.rb

Overview

Sample memory allocations.

~~~ ruby sampler = Sampler.capture do 5.times { “foo” } end ~~~

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&filter) ⇒ Sampler

Returns a new instance of Sampler.



69
70
71
72
73
74
75
# File 'lib/memory/sampler.rb', line 69

def initialize(&filter)
  @filter = filter
  
  @cache = Cache.new
  @wrapper = Wrapper.new(@cache)
  @allocated = Array.new
end

Instance Attribute Details

#allocatedObject (readonly)

Returns the value of attribute allocated.



81
82
83
# File 'lib/memory/sampler.rb', line 81

def allocated
  @allocated
end

#cacheObject (readonly)

Returns the value of attribute cache.



79
80
81
# File 'lib/memory/sampler.rb', line 79

def cache
  @cache
end

#filterObject (readonly)

Returns the value of attribute filter.



77
78
79
# File 'lib/memory/sampler.rb', line 77

def filter
  @filter
end

#wrapperObject (readonly)

Returns the value of attribute wrapper.



80
81
82
# File 'lib/memory/sampler.rb', line 80

def wrapper
  @wrapper
end

Instance Method Details

#dump(io = nil) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
# 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) ⇒ Object



123
124
125
126
127
128
129
# 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

#reportObject



131
132
133
134
135
136
137
# File 'lib/memory/sampler.rb', line 131

def report
  report = Report.general
  
  report.concat(@allocated)
  
  return report
end

#run(&block) ⇒ Object

Collects object allocation and memory of ruby code inside of passed block.



140
141
142
143
144
145
146
147
148
149
# 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

#startObject



83
84
85
86
87
88
89
# File 'lib/memory/sampler.rb', line 83

def start
  GC.disable
  GC.start
  
  @generation = GC.count
  ObjectSpace.trace_object_allocations_start
end

#stopObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# 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