Class: MemoryProfiler::Results

Inherits:
Object
  • Object
show all
Defined in:
lib/memory_profiler/results.rb

Defined Under Namespace

Classes: StringStat

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#strings_allocatedObject

Returns the value of attribute strings_allocated.



35
36
37
# File 'lib/memory_profiler/results.rb', line 35

def strings_allocated
  @strings_allocated
end

#strings_retainedObject

Returns the value of attribute strings_retained.



35
36
37
# File 'lib/memory_profiler/results.rb', line 35

def strings_retained
  @strings_retained
end

#total_allocatedObject

Returns the value of attribute total_allocated.



36
37
38
# File 'lib/memory_profiler/results.rb', line 36

def total_allocated
  @total_allocated
end

#total_retainedObject

Returns the value of attribute total_retained.



36
37
38
# File 'lib/memory_profiler/results.rb', line 36

def total_retained
  @total_retained
end

Class Method Details

.from_raw(allocated, retained, top) ⇒ Object



38
39
40
# File 'lib/memory_profiler/results.rb', line 38

def self.from_raw(allocated, retained, top)
  self.new.register_results(allocated,retained,top)
end

.register_type(name, lookup) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/memory_profiler/results.rb', line 4

def self.register_type(name, lookup)
  ["allocated","retained"].product(["objects","memory"]).each do |type, metric|
    full_name = "#{type}_#{metric}_by_#{name}"
    attr_accessor full_name

    @@lookups ||= []
    mapped = lookup

    if metric == "memory"
      mapped = lambda{|stat|
        [lookup.call(stat), stat.memsize]
      }
    end

    @@lookups << [full_name, mapped]

  end
end

Instance Method Details

#dump(description, data, io) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/memory_profiler/results.rb', line 110

def dump(description, data, io)
  io.puts description
  io.puts "-----------------------------------"
  if data
    data.each do |item|
      io.puts "#{item[:data]} x #{item[:count]}"
    end
  else
    io.puts "NO DATA"
  end
  io.puts
end

#dump_strings(io, title, strings) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/memory_profiler/results.rb', line 97

def dump_strings(io, title, strings)
  return unless strings
  io.puts "#{title} String Report"
  io.puts "-----------------------------------"
  strings.each do |string, stats|
    io.puts "#{string[0..200].inspect} x #{stats.reduce(0){|a,b| a + b[1]}}"
    stats.sort_by{|x,y| -y}.each do |location, count|
      io.puts "    #{location} x #{count}"
    end
  end
  nil
end

#pretty_print(io = STDOUT) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/memory_profiler/results.rb', line 79

def pretty_print(io = STDOUT)
  io.puts "Total allocated #{total_allocated}"
  io.puts "Total retained #{total_retained}"
  io.puts
  ["allocated","retained"]
    .product(["memory", "objects"])
    .product(["gem", "file", "location"])
    .each do |(type, metric), name|
    dump "#{type} #{metric} by #{name}", self.send("#{type}_#{metric}_by_#{name}"), io
  end

  io.puts
  dump_strings(io, "Allocated",strings_allocated)
  io.puts
  dump_strings(io, "Retained",strings_retained)
  nil
end

#register_results(allocated, retained, top) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/memory_profiler/results.rb', line 42

def register_results(allocated, retained, top)
  @@lookups.each do |name, lookup|
    mapped = lambda{|tuple|
        lookup.call(tuple[1])
    }

    result =
      if name =~ /^allocated/
        allocated.top_n(top, &mapped)
      else
        retained.top_n(top, &mapped)
      end

    self.send "#{name}=", result
  end

  self.strings_retained = string_report(retained, top)

  self.total_allocated = allocated.count
  self.total_retained = retained.count

  self
end

#string_report(data, top) ⇒ Object



68
69
70
71
72
73
74
75
76
77
# File 'lib/memory_profiler/results.rb', line 68

def string_report(data, top)
  data
    .keep_if{|id,stat| stat.class_name == "String"}
    .map{|id,stat| [ObjectSpace._id2ref(id), "#{stat.file}:#{stat.line}"]}
    .group_by{|string, location| string}
    .sort_by{|string, list| -list.count}
    .first(top)
    .map{|string,list| [string, list.group_by{|str,location| location}
                                    .map{|location, locations| [location, locations.count]}]}
end