Class: MemoryProfiler::Reporter

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

Overview

Reporter is the top level API used for generating memory reports.

Examples:

Measure object allocation in a block

report = Reporter.report(top: 50) do
  5.times { "foo" }
end

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Reporter

Returns a new instance of Reporter.



18
19
20
21
22
23
# File 'lib/memory_profiler/reporter.rb', line 18

def initialize(opts = {})
  @top          = opts[:top] || 50
  @trace        = opts[:trace] && Array(opts[:trace])
  @ignore_files = opts[:ignore_files] && Regexp.new(opts[:ignore_files])
  @allow_files  = opts[:allow_files] && /#{Array(opts[:allow_files]).join('|')}/
end

Class Attribute Details

.current_reporterObject

Returns the value of attribute current_reporter.



13
14
15
# File 'lib/memory_profiler/reporter.rb', line 13

def current_reporter
  @current_reporter
end

Instance Attribute Details

#generationObject (readonly)

Returns the value of attribute generation.



16
17
18
# File 'lib/memory_profiler/reporter.rb', line 16

def generation
  @generation
end

#report_resultsObject (readonly)

Returns the value of attribute report_results.



16
17
18
# File 'lib/memory_profiler/reporter.rb', line 16

def report_results
  @report_results
end

#topObject (readonly)

Returns the value of attribute top.



16
17
18
# File 'lib/memory_profiler/reporter.rb', line 16

def top
  @top
end

#traceObject (readonly)

Returns the value of attribute trace.



16
17
18
# File 'lib/memory_profiler/reporter.rb', line 16

def trace
  @trace
end

Class Method Details

.report(opts = {}, &block) ⇒ MemoryProfiler::Results

Helper for generating new reporter and running against block.

Parameters:

  • opts (Hash) (defaults to: {})

    the options to create a report with

Options Hash (opts):

  • :top (Object)

    max number of entries to output

  • :trace (Object)

    a class or an array of classes you explicitly want to trace

  • :ignore_files (Object)

    a regular expression used to exclude certain files from tracing

  • :allow_files (Object)

    a string or array of strings to selectively include in tracing

Returns:



32
33
34
# File 'lib/memory_profiler/reporter.rb', line 32

def self.report(opts = {}, &block)
  self.new(opts).run(&block)
end

Instance Method Details

#run(&block) ⇒ Object

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



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/memory_profiler/reporter.rb', line 73

def run(&block)
  start
  begin
    yield
  rescue Exception
    ObjectSpace.trace_object_allocations_stop
    GC.enable
    raise
  else
    stop
  end
end

#startObject



36
37
38
39
40
41
42
43
# File 'lib/memory_profiler/reporter.rb', line 36

def start
  3.times { GC.start }
  GC.start
  GC.disable

  @generation = GC.count
  ObjectSpace.trace_object_allocations_start
end

#stopObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/memory_profiler/reporter.rb', line 45

def stop
  ObjectSpace.trace_object_allocations_stop
  allocated = object_list(generation)
  retained = StatHash.new.compare_by_identity

  GC.enable
  # for whatever reason doing GC in a block is more effective at
  # freeing objects.
  # full_mark: true, immediate_mark: true, immediate_sweep: true are already default
  3.times { GC.start }
  # another start outside of the block to release the block
  GC.start

  # Caution: 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.

  ObjectSpace.each_object do |obj|
    next unless ObjectSpace.allocation_generation(obj) == generation
    found = allocated[obj.__id__]
    retained[obj.__id__] = found if found
  end
  ObjectSpace.trace_object_allocations_clear

  @report_results = Results.new
  @report_results.register_results(allocated, retained, top)
end