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