Class: MemKit::Profiler

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

Class Method Summary collapse

Class Method Details

.format_size(bytes) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/mem_kit/profiler.rb', line 63

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



4
5
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
45
46
47
48
49
50
51
52
53
54
# File 'lib/mem_kit/profiler.rb', line 4

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

  require 'objspace'

  @thread = Thread.new do

    while @is_running == true do

      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

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

      sleep(interval)

    end

  end

  return @thread

end

.stopObject



56
57
58
59
60
61
# File 'lib/mem_kit/profiler.rb', line 56

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

.update_object(object, result, total_memory_size) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/mem_kit/profiler.rb', line 78

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_all(object.class)
    obj = { klass: object.class, allocation_count: 1, memory_usage_size: format_size(mem_usage), memory_usage_percentage: "#{(mem_usage.to_f / total_memory_size.to_f * 100.0).round(2)}%", bytes: mem_usage }
    result[:objects].push(obj)
  else
    obj[:allocation_count] += 1
  end
  return obj
end