Class: MemKit::Profiler

Inherits:
Object
  • Object
show all
Defined in:
lib/mem_kit/profiler.rb

Class Method Summary collapse

Class Method Details

.collect(limit: nil) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mem_kit/profiler.rb', line 46

def self.collect(limit: nil)

  total_memory_size = ObjectSpace.memsize_of_all

  result = { total_memory_usage: format_size(total_memory_size), total_allocations: ObjectSpace.each_object{}, objects: [] }

  ObjectSpace.each_object do |o|
    update_object(o, result, total_memory_size)
  end

  result[:objects].sort! { |a,b| b[:bytes] <=> a[:bytes] }

  if limit != nil
    result[:objects] = result[:objects][0, limit]
  end

  return result

end

.format_percentage(value, total) ⇒ Object



103
104
105
# File 'lib/mem_kit/profiler.rb', line 103

def self.format_percentage(value, total)
  return "#{(value.to_f / total.to_f * 100.0).round(2)}%"
end

.format_size(bytes) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/mem_kit/profiler.rb', line 73

def self.format_size(bytes)
  value = bytes
  unit = 'Bytes'
  if bytes >= 100000
    #format as MB
    value = bytes.to_f / 1000.0 / 1000.0
    unit = 'MB'
  elsif bytes >= 500
    #format as KB
    value = bytes.to_f / 1000.0
    unit = 'KB'
  end
  return "#{value.round(2)} #{unit}"
end

.start(logger: nil, interval: 240, limit: nil) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/mem_kit/profiler.rb', line 6

def self.start(logger: nil, interval: 240, limit: nil)

  if logger == nil
    logger = Logger.new(STDOUT)
  end

  logger.debug("[MemKit::Profiler] - Starting Memory Profiling. Interval: #{interval} seconds | Limit: #{limit || 'N/A'}.")

  %w'INT TERM'.each do |sig|
    Signal.trap(sig) {
      stop
    }
  end

  if @is_running == true
    raise "[MemKit::Profiler] - Profiler is already running."
  end

  @is_running = true

  @thread = Thread.new do

    while @is_running == true do

      GC.start

      result = collect(limit: limit)

      logger.debug("[MemKit::Profiler}] - #{JSON.dump(result)}")

      sleep(interval)

    end

  end

  return @thread

end

.stopObject



66
67
68
69
70
71
# File 'lib/mem_kit/profiler.rb', line 66

def self.stop
  @is_running = false
  if @thread != nil
    Thread.kill(@thread)
  end
end

.update_object(object, result, total_memory_size) ⇒ Object



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

def self.update_object(object, result, total_memory_size)
  obj = result[:objects].detect { |o| o[:klass] == object.class }
  if obj == nil
    mem_usage = ObjectSpace.memsize_of(object)
    obj = { klass: object.class, allocation_count: 1, memory_usage_size: format_size(mem_usage), memory_usage_percentage: format_percentage(mem_usage, total_memory_size), bytes: mem_usage }
    result[:objects].push(obj)
  else
    obj[:allocation_count] += 1
    obj[:bytes] += ObjectSpace.memsize_of(object)
    obj[:memory_usage_size] = format_size(obj[:bytes])
    obj[:memory_usage_percentage] = format_percentage(obj[:bytes], total_memory_size)
  end
  return obj
end