Class: HeapScope::RetentionSession

Inherits:
Object
  • Object
show all
Defined in:
lib/heapscope/retention.rb

Overview

Multi-cycle retention analysis. Tracks populations that survive GC repeatedly.

Defined Under Namespace

Classes: Sample

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(force_gc: true, mode: :lightweight, metadata: {}) ⇒ RetentionSession

Returns a new instance of RetentionSession.



10
11
12
13
14
15
16
17
# File 'lib/heapscope/retention.rb', line 10

def initialize(force_gc: true, mode: :lightweight, metadata: {})
  @force_gc = force_gc
  @mode = mode
  @metadata = 
  @samples = []
  @config = HeapScope.config
  @collector = Collector.new
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



8
9
10
# File 'lib/heapscope/retention.rb', line 8

def config
  @config
end

#force_gcObject (readonly)

Returns the value of attribute force_gc.



8
9
10
# File 'lib/heapscope/retention.rb', line 8

def force_gc
  @force_gc
end

#samplesObject (readonly)

Returns the value of attribute samples.



8
9
10
# File 'lib/heapscope/retention.rb', line 8

def samples
  @samples
end

Instance Method Details

#class_seriesObject



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/heapscope/retention.rb', line 33

def class_series
  names = samples.flat_map { |s| s.snapshot.class_stats.keys }.uniq
  names.each_with_object({}) do |name, hash|
    series = samples.map { |s| s.snapshot.class_count(name) }
    hash[name] = {
      name: name,
      series: series,
      trend: Growth.analyze(series),
      delta: series.last.to_i - series.first.to_i
    }
  end
end

#finishObject



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

def finish
  Report.from_retention_session(self)
end

#persistent_classes(min_cycles: 3, min_delta: 10) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/heapscope/retention.rb', line 46

def persistent_classes(min_cycles: 3, min_delta: 10)
  class_series.values.select do |entry|
    trend = entry[:trend]
    next false if entry[:series].size < min_cycles
    next false if entry[:delta] < min_delta
    next false if config.ignore_class?(entry[:name])

    %i[monotonic_growth linear_growth exponential_like].include?(trend[:pattern])
  end.sort_by { |e| -e[:delta] }
end

#sample(label: nil) ⇒ Object



19
20
21
22
23
24
25
26
27
# File 'lib/heapscope/retention.rb', line 19

def sample(label: nil)
  GC.start if force_gc
  snap = @collector.capture(
    mode: @mode,
    metadata: @metadata.merge(sample_index: @samples.size, label: label)
  )
  @samples << Sample.new(index: @samples.size, snapshot: snap, after_gc: force_gc)
  snap
end