Class: MemoryProfiler
- Inherits:
-
Object
- Object
- MemoryProfiler
- Defined in:
- lib/memory_profiler.rb
Constant Summary collapse
Class Method Summary collapse
- .hook(klass, meth) ⇒ Object
- .log(o) ⇒ Object
-
.profile(delay = 2, limit = 10, output = $stderr) ⇒ Object
profile is a CLEAN, totally minimal memory profiler:.
- .report ⇒ Object
- .spy_on(*klasses) ⇒ Object
Class Method Details
.hook(klass, meth) ⇒ Object
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/memory_profiler.rb', line 80 def self.hook klass, meth klass.module_eval do old = meth.to_s.sub(/%/, 'pct').sub(/^/, 'old_') alias_method old, meth eval "def #{meth}(*args, &block) MemoryProfiler.log(self) #{old}(*args, &block) end" end end |
.log(o) ⇒ Object
61 62 63 64 65 66 67 68 |
# File 'lib/memory_profiler.rb', line 61 def self.log(o) loc = caller[1] unless @@locations.has_key? loc then @@locations[loc] = @@locations.size end loc = @@locations[loc] @@allocations[o.class][loc] += 1 end |
.profile(delay = 2, limit = 10, output = $stderr) ⇒ Object
profile is a CLEAN, totally minimal memory profiler:
-
1 thread
-
2 hashes (curr, prev)
-
classes as keys
-
fixnums as values.
No extra memory required if I can help it. Keep it as simple as possible. The code at the link above is WAY to complex for such a simple task. It does use a sort_by, so that produces a bit extra junk… but that shouldn’t be more than an extra array and hash per iteration.
Just fire it up as MemoryProfiler.profile or use it with a block of code:
MemoryProfiler.profile do
# ...
end
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/memory_profiler.rb', line 24 def self.profile(delay = 2, limit=10, output=$stderr) Thread.abort_on_exception = true totals = Hash.new(0) t = Thread.new do prev = Hash.new(0) curr = Hash.new(0) loop do curr.clear ObjectSpace.each_object do |o| curr[o.class] += 1 end curr.each do |k,v| curr[k] -= prev[k] end puts curr.sort_by { |k,v| -v }.first(limit).each do |k,v| output.printf "%+5d: %s\n", v, k.name unless v == 0 end prev.clear prev.update curr curr.each do |k,n| totals[k] += n end sleep delay end end if block_given? then yield t.exit end totals end |
.report ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/memory_profiler.rb', line 91 def self.report keys = @@locations.invert puts puts "############################################################" puts "Spy Report:" @@allocations.each do |klass, locations| puts puts klass puts locations.sort_by { |k,v| -v }.first(10).each do |location, count| printf "%6d: %s\n", count, keys[location] end end p @@locations, @@allocations, keys if $DEBUG end |
.spy_on(*klasses) ⇒ Object
70 71 72 73 74 75 76 77 78 |
# File 'lib/memory_profiler.rb', line 70 def self.spy_on *klasses klasses.each do |klass| hook klass, :initialize if klass == String then hook klass, :% hook klass, :strip end end end |