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

#pretty_print(io = STDOUT, **options) ⇒ Object



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

def pretty_print(io = STDOUT, **options)
  io = File.open(options[:to_file], "w") if options[:to_file]

  color_output = options.fetch(:color_output) { io.respond_to?(:isatty) && io.isatty }
  @colorize = color_output ? Polychrome.new : Monochrome.new

  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)

  io.close if io.is_a? File
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
      .reject { |id, stat| stat.class_name != "String" }
      .map { |id, stat| [begin; ObjectSpace._id2ref(id); rescue "__UNKNOWN__"; end, "#{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