Class: HeapScope::Diff

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

Overview

Rich comparison between two snapshots.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(before, after) ⇒ Diff

Returns a new instance of Diff.



9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/heapscope/diff.rb', line 9

def initialize(before, after)
  @before = before
  @after = after
  @warnings = []
  @warnings << "snapshots_from_different_processes" unless before.same_process?(after)
  @class_deltas = compute_class_deltas
  @rss_delta = delta(after.rss_bytes, before.rss_bytes)
  @heap_live_delta = delta(after.heap_live_slots, before.heap_live_slots)
  @allocated_delta = delta(after.total_allocated_objects, before.total_allocated_objects)
  @freed_delta = delta(after.total_freed_objects, before.total_freed_objects)
  @allocation_deltas = compute_allocation_deltas
end

Instance Attribute Details

#afterObject (readonly)

Returns the value of attribute after.



6
7
8
# File 'lib/heapscope/diff.rb', line 6

def after
  @after
end

#allocated_deltaObject (readonly)

Returns the value of attribute allocated_delta.



6
7
8
# File 'lib/heapscope/diff.rb', line 6

def allocated_delta
  @allocated_delta
end

#allocation_deltasObject (readonly)

Returns the value of attribute allocation_deltas.



6
7
8
# File 'lib/heapscope/diff.rb', line 6

def allocation_deltas
  @allocation_deltas
end

#beforeObject (readonly)

Returns the value of attribute before.



6
7
8
# File 'lib/heapscope/diff.rb', line 6

def before
  @before
end

#class_deltasObject (readonly)

Returns the value of attribute class_deltas.



6
7
8
# File 'lib/heapscope/diff.rb', line 6

def class_deltas
  @class_deltas
end

#freed_deltaObject (readonly)

Returns the value of attribute freed_delta.



6
7
8
# File 'lib/heapscope/diff.rb', line 6

def freed_delta
  @freed_delta
end

#heap_live_deltaObject (readonly)

Returns the value of attribute heap_live_delta.



6
7
8
# File 'lib/heapscope/diff.rb', line 6

def heap_live_delta
  @heap_live_delta
end

#rss_deltaObject (readonly)

Returns the value of attribute rss_delta.



6
7
8
# File 'lib/heapscope/diff.rb', line 6

def rss_delta
  @rss_delta
end

#warningsObject (readonly)

Returns the value of attribute warnings.



6
7
8
# File 'lib/heapscope/diff.rb', line 6

def warnings
  @warnings
end

Instance Method Details

#freed_classes(limit = 20) ⇒ Object



47
48
49
50
51
# File 'lib/heapscope/diff.rb', line 47

def freed_classes(limit = 20)
  class_deltas.select { |d| d[:delta_count].negative? }
              .sort_by { |d| d[:delta_count] }
              .first(limit)
end

#growing_classes(limit = 20) ⇒ Object



41
42
43
44
45
# File 'lib/heapscope/diff.rb', line 41

def growing_classes(limit = 20)
  class_deltas.select { |d| d[:delta_count].positive? }
              .sort_by { |d| -d[:delta_count] }
              .first(limit)
end

#heap_bytes_estimate_deltaObject



64
65
66
# File 'lib/heapscope/diff.rb', line 64

def heap_bytes_estimate_delta
  class_deltas.sum { |d| d[:delta_bytes] }
end

#native_memory_mismatch?Boolean

Returns:

  • (Boolean)


57
58
59
60
61
62
# File 'lib/heapscope/diff.rb', line 57

def native_memory_mismatch?
  return false if rss_delta.nil? || heap_live_delta.nil?

  rss_delta > 10 * 1024 * 1024 && heap_live_delta < 50_000 &&
    (rss_delta > heap_bytes_estimate_delta * 3)
end

#new_classesObject



53
54
55
# File 'lib/heapscope/diff.rb', line 53

def new_classes
  class_deltas.select { |d| d[:before_count].zero? && d[:after_count].positive? }
end

#retention_ratioObject



28
29
30
31
32
33
34
35
# File 'lib/heapscope/diff.rb', line 28

def retention_ratio
  return nil if allocated_delta.nil? || allocated_delta <= 0

  surviving = surviving_estimate
  return nil if surviving.nil?

  surviving.to_f / allocated_delta
end

#surviving_estimateObject



22
23
24
25
26
# File 'lib/heapscope/diff.rb', line 22

def surviving_estimate
  return nil if allocated_delta.nil? || freed_delta.nil?

  allocated_delta - freed_delta
end

#to_hObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/heapscope/diff.rb', line 68

def to_h
  {
    before_id: before.id,
    after_id: after.id,
    rss_delta: rss_delta,
    heap_live_delta: heap_live_delta,
    allocated_delta: allocated_delta,
    freed_delta: freed_delta,
    surviving_estimate: surviving_estimate,
    retention_ratio: retention_ratio,
    class_deltas: class_deltas,
    allocation_deltas: allocation_deltas,
    warnings: warnings,
    native_memory_mismatch: native_memory_mismatch?
  }
end

#to_table(format: :ascii, limit: 15) ⇒ Object



85
86
87
# File 'lib/heapscope/diff.rb', line 85

def to_table(format: :ascii, limit: 15)
  Tables.class_growth(self, limit: limit, format: format)
end

#top_growth(limit = 20) ⇒ Object



37
38
39
# File 'lib/heapscope/diff.rb', line 37

def top_growth(limit = 20)
  class_deltas.sort_by { |d| -d[:delta_count].abs }.first(limit)
end