Class: AllocationStats

Inherits:
Object
  • Object
show all
Defined in:
lib/allocation_stats.rb,
lib/allocation_stats/allocation.rb,
lib/allocation_stats/allocations_proxy.rb

Overview

Copyright 2013 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0, found in the LICENSE file.

Defined Under Namespace

Classes: Allocation, AllocationsProxy

Constant Summary collapse

RUBYLIBDIR =

a convenience constant

RbConfig::CONFIG["rubylibdir"]
GEMDIR =

a convenience constant

Gem.dir

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(burn: 0) ⇒ AllocationStats

Returns a new instance of AllocationStats.



40
41
42
43
44
45
# File 'lib/allocation_stats.rb', line 40

def initialize(burn: 0)
  @burn = burn
  # Copying ridiculous workaround from:
  # https://github.com/ruby/ruby/commit/7170baa878ac0223f26fcf8c8bf25492415e6eaa
  Class.name
end

Instance Attribute Details

#burnFixnum

burn count for block tracing. Defaults to 0. When called with a block,

trace will yield the block @burn-times before actually tracing the object

allocations. This offers the benefit of pre-memoizing objects, and loading any required Ruby files before tracing.

Returns:

  • (Fixnum)


27
28
29
# File 'lib/allocation_stats.rb', line 27

def burn
  @burn
end

#gc_profiler_reportObject

Returns the value of attribute gc_profiler_report.



29
30
31
# File 'lib/allocation_stats.rb', line 29

def gc_profiler_report
  @gc_profiler_report
end

#new_allocationsArray (readonly)

allocation data for all new objects that were allocated during the #initialize block. It is better to use #allocations, which returns an AllocationsProxy, which has a much more convenient, domain-specific API for filtering, sorting, and grouping Allocation objects, than this plain Array object.

Returns:

  • (Array)


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

def new_allocations
  @new_allocations
end

Class Method Details

.trace(&block) ⇒ Object



47
48
49
50
# File 'lib/allocation_stats.rb', line 47

def self.trace(&block)
  allocation_stats = AllocationStats.new
  allocation_stats.trace(&block)
end

Instance Method Details

#allocations(alias_paths: false) ⇒ Object

Proxy for the @new_allocations array that allows for individual filtering, sorting, and grouping of the Allocation objects.



130
131
132
# File 'lib/allocation_stats.rb', line 130

def allocations(alias_paths: false)
  AllocationsProxy.new(@new_allocations, alias_paths: alias_paths)
end

#collect_new_allocationsObject



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/allocation_stats.rb', line 103

def collect_new_allocations
  @new_allocations = []
  ObjectSpace.each_object.to_a.each do |object|
    next if ObjectSpace.allocation_sourcefile(object).nil?
    next if ObjectSpace.allocation_sourcefile(object) == __FILE__
    next if @existing_object_ids[object.__id__ / 1000] &&
            @existing_object_ids[object.__id__ / 1000].include?(object.__id__)

    @new_allocations << Allocation.new(object)
  end
end

#inspectObject

Inspect @new_allocations, the canonical array of Allocation objects.



124
125
126
# File 'lib/allocation_stats.rb', line 124

def inspect
  @new_allocations.inspect
end

#startObject

Begin tracing object allocations. Tracing must be stopped with AllocationStats#stop. Garbage collection is disabled while tracing is enabled.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/allocation_stats.rb', line 87

def start
  GC.start
  GC.disable

  @existing_object_ids = {}

  ObjectSpace.each_object.to_a.each do |object|
    @existing_object_ids[object.__id__ / 1000] ||= []
    @existing_object_ids[object.__id__ / 1000] << object.__id__
  end

  ObjectSpace.trace_object_allocations_start

  return self
end

#stopObject

Stop tracing object allocations that was started with AllocationStats#start.



116
117
118
119
120
121
# File 'lib/allocation_stats.rb', line 116

def stop
  collect_new_allocations
  ObjectSpace.trace_object_allocations_stop
  ObjectSpace.trace_object_allocations_clear
  profile_and_start_gc
end

#trace(&block) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/allocation_stats.rb', line 52

def trace(&block)
  if block_given?
    trace_block(&block)
  else
    start
  end
end

#trace_blockObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/allocation_stats.rb', line 60

def trace_block
  @burn.times { yield }

  GC.start
  GC.disable

  @existing_object_ids = {}

  ObjectSpace.each_object.to_a.each do |object|
    @existing_object_ids[object.__id__ / 1000] ||= []
    @existing_object_ids[object.__id__ / 1000] << object.__id__
  end

  ObjectSpace.trace_object_allocations {
    yield
  }

  collect_new_allocations
  ObjectSpace.trace_object_allocations_clear
  profile_and_start_gc

  return self
end