Module: DeadBro::GcTracker

Defined in:
lib/dead_bro/gc_tracker.rb

Constant Summary collapse

THREAD_KEY =
:dead_bro_gc_start

Class Method Summary collapse

Class Method Details

.diff(before, after) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/dead_bro/gc_tracker.rb', line 32

def self.diff(before, after)
  return {} if before.empty? || after.empty?
  gc_time_ms = if before[:gc_time_ns] && after[:gc_time_ns]
    ((after[:gc_time_ns] - before[:gc_time_ns]) / 1_000_000.0).round(3)
  end
  {
    minor_gc_runs: (after[:minor_gc_count] || 0) - (before[:minor_gc_count] || 0),
    major_gc_runs: (after[:major_gc_count] || 0) - (before[:major_gc_count] || 0),
    allocated_objects: (after[:total_allocated_objects] || 0) - (before[:total_allocated_objects] || 0),
    gc_time_ms: gc_time_ms
  }
rescue
  {}
end

.snapshotObject



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/dead_bro/gc_tracker.rb', line 19

def self.snapshot
  return {} unless defined?(GC) && GC.respond_to?(:stat)
  stat = GC.stat
  {
    minor_gc_count: stat[:minor_gc_count] || 0,
    major_gc_count: stat[:major_gc_count] || 0,
    total_allocated_objects: stat[:total_allocated_objects] || 0,
    gc_time_ns: GC.respond_to?(:total_time) ? GC.total_time : nil
  }
rescue
  {}
end

.start_request_trackingObject



7
8
9
# File 'lib/dead_bro/gc_tracker.rb', line 7

def self.start_request_tracking
  Thread.current[THREAD_KEY] = snapshot
end

.stop_request_trackingObject



11
12
13
14
15
16
17
# File 'lib/dead_bro/gc_tracker.rb', line 11

def self.stop_request_tracking
  before = Thread.current[THREAD_KEY]
  return {} if before.nil? || before.empty?
  diff(before, snapshot)
ensure
  Thread.current[THREAD_KEY] = nil
end