RAILS_ROOT = File.dirname(__FILE__)+'/../'
class MemoryProfiler
def initialize(method_name)
@object_ids = []
@leaked_objects = []
@methodlog = "#{RAILS_ROOT}/log/#{method_name}_profile.log"
end
def start
GC.start
ObjectSpace.each_object do |o|
@object_ids << o.object_id
end
end
def end
GC.start
ObjectSpace.each_object do |o|
@leaked_objects << o.object_id
end
@leaked_objects = @leaked_objects - @object_ids
puts "Oops..You've got #{@leaked_objects.size} screwed up objects!!" unless @leaked_objects.empty?
File.open(@methodlog,'w') do |f|
@leaked_objects.each do |o|
begin
f.puts ObjectSpace._id2ref(o).inspect
rescue Exception => e
puts "Something wrong happened while processing object #{o}"
end
end
end
end
end
module LeakSpector
def self.included(base)
base.extend LeakSpectorClassMethods
end
module LeakSpectorClassMethods
def leakspect(method)
define_method(:"#{method.to_s}_with_inspection") do |*args|
mp = MemoryProfiler.new(method.to_s)
mp.start
self.send "#{method.to_s}_without_inspection", *args
mp.end
end
#alias_method_chain method, :inspection
alias_method :"#{method.to_s}_without_inspection", method
alias_method method, :"#{method.to_s}_with_inspection"
end
end
end
class << self
include LeakSpector
def leaker
y = "hello"
end
leakspect :leaker
end
leaker