Class: Memory_leak_helper

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

Constant Summary collapse

INSTANCE =

Only one instance is needed. Define that as a constant.

Memory_leak_helper.new

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMemory_leak_helper

Constructor. Spawns used hashes.



7
8
9
10
11
# File 'lib/memory_leak_helper.rb', line 7

def initialize
  @objects_alive = {}
  @objects_data = {}
  @mutex = Monitor.new
end

Instance Attribute Details

#objects_aliveObject (readonly)

Returns the value of attribute objects_alive.



4
5
6
# File 'lib/memory_leak_helper.rb', line 4

def objects_alive
  @objects_alive
end

Instance Method Details

#object_finalized(obj_id) ⇒ Object

Called when an object is finalized. This helps decrease the object-count of a callback.



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/memory_leak_helper.rb', line 37

def object_finalized(obj_id)
  @mutex.synchronize do
    return nil if !@objects_data.key?(obj_id)
    
    backtrace_str = @objects_data[obj_id][:backtrace_str]
    class_name = @objects_data[obj_id][:class_name]
    @objects_data.delete(obj_id)
    
    @objects_alive[class_name][backtrace_str][:count] -= 1
    @objects_alive[class_name].delete(backtrace_str) if @objects_alive[class_name][backtrace_str][:count] <= 0
  end
end

#possible_leaks(args = nil) ⇒ Object

Returns an array of possible leaks.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/memory_leak_helper.rb', line 51

def possible_leaks(args = nil)
  if args and args[:minimum]
    minimum = args[:minimum]
  else
    minimum = 40
  end
  
  @mutex.synchronize do
    leaks = []
    @objects_alive.clone.each do |class_name, backtrace_strs|
      backtrace_strs.each do |backtrace_str, data|
        if data[:count] >= minimum
          leaks << {
            :classname => class_name,
            :backtrace => data[:backtrace],
            :count => data[:count]
          }
        end
      end
    end
    
    leaks.sort! do |ele1, ele2|
      ele2[:count] <=> ele1[:count]
    end
    
    return leaks
  end
end

#register_object(args) ⇒ Object

Registers the object in the leak-helper hash.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/memory_leak_helper.rb', line 14

def register_object(args)
  @mutex.synchronize do
    return nil if !@objects_alive
    
    obj, backtrace_arr = args[:obj], args[:caller]
    obj_id = obj.__id__
    
    class_name = obj.class.name
    backtrace_str = backtrace_arr.join("___")
    
    #Increase count of object-callback.
    @objects_alive[class_name] = {} if !@objects_alive.key?(class_name)
    @objects_alive[class_name][backtrace_str] = {:count => 0, :backtrace => backtrace_arr} if !@objects_alive[class_name].key?(backtrace_str)
    @objects_alive[class_name][backtrace_str][:count] += 1
    
    #Spawn some data to help unsetting it again.
    @objects_data[obj_id] = {:backtrace_str => backtrace_str, :class_name => class_name}
    
    ObjectSpace.define_finalizer(obj, self.method(:object_finalized))
  end
end