Revision: 66058
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at March 6, 2014 19:11 by kulmala
Initial Code
# http://www.happybootstrapper.com/2014/profile-leaky-sidekiq-job-heroku
# Uses Ruby-Prof in dev env, add the following to gemfile development section:
# gem 'ruby-prof'
module MemTool
def self.start(file_name = 'no_name')
unless Rails.env.test?
begin
start_profiling(file_name)
rescue => e
Rails.logger.warn(sprintf 'MemTool: %s', e.message)
end
end
end
def self.stop
unless Rails.env.test?
begin
stop_profiling
rescue => e
Rails.logger.warn(sprintf 'MemTool: %s', e.message)
end
end
end
def self.object_stats
stats = Hash.new(0)
ObjectSpace.each_object { |o| stats[o.class] += 1 }
stats
end
def self.get_memory_usage
`ps -o rss= -p #{Process.pid}`.to_i
end
private
def self.to_sorted_array(hsh)
hsh.sort { |a, b| b[1] <=>a[1] }.collect { |k, v| "#{k}: #{v}" }
end
def self.start_profiling(file_name)
@file_name = file_name
@object_stats = object_stats
@memory_stats = {memory_usage: get_memory_usage}
@gc_stats = GC.stat
RubyProf.start unless Rails.env.production?
end
def self.stop_profiling
result = RubyProf.stop unless Rails.env.production?
new_gc_stats = GC.stat
new_memory_stats = {memory_usage: get_memory_usage}
new_object_stats = object_stats
if Rails.env.production?
log_other_stats(new_gc_stats, new_object_stats, new_memory_stats)
else
time = DateTime.now.to_i
print_ruby_prof_stats(result, time)
print_other_stats(new_gc_stats, new_object_stats, new_memory_stats, time)
end
clean_up
end
def self.clean_up
@file_name = nil
@gc_stats = nil
@object_stats = nil
@memory_stats = nil
end
def self.print_ruby_prof_stats(result, time)
html_file = open_file_for_writing time, 'html'
printer = RubyProf::GraphHtmlPrinter.new(result)
printer.print(html_file, :min_percent => 5)
html_file.close
end
def self.log_other_stats(new_gc_stats, new_object_stats, new_memory_stats)
# The sleeps help the log lines to get into right order
Rails.logger.info 'Memory Profile for ' << @file_name
Rails.logger.info "**** MEMORY ****"
sleep(1.0/20.0)
log_stats new_memory_stats, @memory_stats
sleep(1.0/20.0)
Rails.logger.info "**** GARBAGE COLLECTOR ****"
sleep(1.0/20.0)
log_stats new_gc_stats, @gc_stats
sleep(1.0/20.0)
Rails.logger.info "**** OBJECTS IN MEMORY ****"
sleep(1.0/20.0)
log_stats new_object_stats, @object_stats
end
def self.print_other_stats(new_gc_stats, new_object_stats, new_memory_stats, time)
text_file = open_file_for_writing time, 'txt'
text_file.puts "**** MEMORY ****"
print_stats new_memory_stats, @memory_stats, text_file
text_file.puts "\n"
text_file.puts "**** GARBAGE COLLECTOR ****"
print_stats new_gc_stats, @gc_stats, text_file
text_file.puts "\n"
text_file.puts "**** OBJECTS IN MEMORY ****"
print_stats new_object_stats, @object_stats, text_file
text_file.close
end
def self.open_file_for_writing(time, suffix)
File.new "#{Rails.root}/log/#{time}_#{@file_name}.#{suffix}", 'a+'
end
def self.print_stats(stats, last_stats, out)
title = sprintf("%10s | %10s |", 'Before', 'Delta')
out.puts title
line_format = "%10d | %10d | %-30s"
stats.sort { |(k1, v1), (k2, v2)| v2 <=> v1 }.each do |key, value|
delta = 0
if last_stats[key]
delta = value - last_stats[key]
end
log_entry = sprintf(line_format, value, delta, key)
out.puts log_entry
end
end
def self.log_stats(stats, last_stats)
title = sprintf("%10s | %10s |", 'Before', 'Delta')
Rails.logger.info title
# filter away classes with less than 10 instances
stats.reject! { |key, value| value < 10 }
line_format = "%10d | %10d | %-30s"
stats.sort { |(k1, v1), (k2, v2)| v2 <=> v1 }.each do |key, value|
delta = 0
if last_stats[key]
delta = value - last_stats[key]
end
log_entry = sprintf(line_format, value, delta, key)
Rails.logger.info log_entry
end
end
end
Initial URL
http://www.happybootstrapper.com/2014/profile-leaky-sidekiq-job-heroku
Initial Description
A little tool for debugging memory problems in Heroku. Works also in Mac. Instructions and further in info at http://www.happybootstrapper.com/2014/profile-leaky-sidekiq-job-heroku
Initial Title
MemTool for Ruby 2.0 & Rails 4.0
Initial Tags
Initial Language
Rails