class Memory_leak_helper

Constants

INSTANCE

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

Attributes

objects_alive[R]

Public Class Methods

new() click to toggle source

Constructor. Spawns used hashes.

# File lib/memory_leak_helper.rb, line 7
def initialize
  @objects_alive = {}
  @objects_data = {}
  @mutex = Monitor.new
end

Public Instance Methods

object_finalized(obj_id) click to toggle source

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

# 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) click to toggle source

Returns an array of possible leaks.

# 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) click to toggle source

Registers the object in the leak-helper hash.

# 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