module BusyAdministrator::MemoryUtils
Public Class Methods
get_created_object_classes()
click to toggle source
# File lib/busy-administrator/memory_utils.rb, line 48 def get_created_object_classes ObjectSpace.each_object.to_a.map(&:class).uniq.select do |target| target.is_a?(Class) || target.is_a?(Module) end end
profile(gc_enabled: true, verbose: false) { |analyzer| ... }
click to toggle source
# File lib/busy-administrator/memory_utils.rb, line 54 def profile(gc_enabled: true, verbose: false) analyzer = MemoryAnalyzer.new excluded_object_id_storage = [] all_object_ids_after_execution = [] gc_count_before = 0 output_container = { memory_usage: {}, total_time: 0.0, gc: { count: 0, enabled: false } } action("GC Settings") do output_container[:gc][:enabled] = gc_enabled if gc_enabled GC.enable log("[Before] Enable GC", verbose: verbose) else GC.disable log("[Before] Disable GC", verbose: verbose) end end action("Prepare Object ID Storage Before Execution") do excluded_object_id_storage = get_created_object_ids log("[Before] Object Count: #{ excluded_object_id_storage.size }", verbose: verbose) end action("Get Memory Usage Before Execution") do memory_usage_before = ProcessUtils.get_memory_usage(:rss) output_container[:memory_usage][:before] = memory_usage_before log("[Before] Memory Usage: #{ memory_usage_before }", verbose: verbose) end action("Execute Main Action") do gc_count_before = GC.stat[:count] log("[Before] GC Count: #{ gc_count_before }", verbose: verbose) log("[Before] Block Start", verbose: verbose) total_time = Benchmark.realtime do yield(analyzer) if block_given? end output_container[:total_time] = total_time.round(6) log("[After] Block End", verbose: verbose) log("[After] Total Time: #{ total_time } seconds", verbose: verbose) end action("Compute Specific Stats") do output_container[:specific] = analyzer.analyze(verbose: verbose) end action("Run GC if enabled") do if gc_enabled self.trigger_gc log("[After] Run GC", verbose: verbose) end gc_count_after = GC.stat[:count] log("[After] GC Count: #{ gc_count_after }", verbose: verbose) gc_count_diff = gc_count_after - gc_count_before output_container[:gc][:count] = gc_count_diff log("[Diff] GC Count: #{ gc_count_diff }", verbose: verbose) end action("Get Memory Usage After Execution") do memory_usage_after = ProcessUtils.get_memory_usage(:rss) log("[After] Memory Usage: #{ memory_usage_after }", verbose: verbose) output_container[:memory_usage][:after] = memory_usage_after output_container[:memory_usage][:diff] = output_container[:memory_usage][:after] - output_container[:memory_usage][:before] log("[Diff] Memory Usage: #{ output_container[:memory_usage] }", verbose: verbose) end action("Get Object Count After Execution") do all_object_ids_after_execution = get_created_object_ids log("[After] Object Count: #{ all_object_ids_after_execution.size }", verbose: verbose) all_object_ids_after_execution -= excluded_object_id_storage log("[Diff] Object Count: #{ all_object_ids_after_execution.size }", verbose: verbose) output_container[:object_count] = all_object_ids_after_execution.size end action("Compute General Stats") do general = {} all_object_ids_after_execution.each do |object_id| target = ObjectSpace._id2ref(object_id) rescue nil if target_class = target.class.name rescue nil general[target_class.to_sym] ||= 0 general[target_class.to_sym] += ObjectSpace.memsize_of(target) end end general.each do |key, value| general[key] = MemorySize.new(bytes: value) log("[Diff] Class #{ key }: #{ general[key] } ") end output_container[:general] = general end action("Run GC") do GC.enable self.trigger_gc end output_container end
trigger_gc()
click to toggle source
# File lib/busy-administrator/memory_utils.rb, line 44 def trigger_gc GC.start(full_mark:true, immediate_sweep: true, immediate_mark: false) end
Private Class Methods
action(label) { || ... }
click to toggle source
# File lib/busy-administrator/memory_utils.rb, line 176 def action(label) log("Action: #{ label }") yield if block_given? end
get_created_object_ids()
click to toggle source
# File lib/busy-administrator/memory_utils.rb, line 188 def get_created_object_ids output = ObjectSpace.each_object.to_a.map(&:object_id) output << output.object_id output end
get_unique_classes_from_object_ids(object_ids_array)
click to toggle source
# File lib/busy-administrator/memory_utils.rb, line 195 def get_unique_classes_from_object_ids(object_ids_array) object_ids_array.map { |object_id| ObjectSpace._id2ref(object_id) }.map(&:class).uniq.select do |target| target.is_a?(Class) || target.is_a?(Module) end end
log(message, verbose: false)
click to toggle source
# File lib/busy-administrator/memory_utils.rb, line 182 def log(message, verbose: false) if verbose puts "[BusyAdministrator::MemoryUtils.profile] #{ message }" end end