Created
April 9, 2014 00:17
-
-
Save akitaonrails/10212233 to your computer and use it in GitHub Desktop.
Just a hack to make it easier to understand GC.stat in Ruby 2.0 and 2.1 (made for a tech talk)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is an attempt to translate GC.stat to a more understandable format for humans | |
# from @samsaffron | |
# http://samsaffron.com/archive/2013/11/22/demystifying-the-ruby-gc?utm_source=rubyweekly&utm_medium=email | |
# http://samsaffron.com/archive/2014/04/08/ruby-2-1-garbage-collection-ready-for-production | |
def gc_stats | |
stats = GC.stat | |
space_count = ObjectSpace.count_objects | |
objects_per_heap = space_count[:TOTAL] / stats[:heap_used] | |
report = { | |
objects_per_heap: objects_per_heap, | |
heaps_with_used_slots: stats[:heap_used], | |
total_heaps_allocated: stats[:heap_length], | |
total_heaps_allocated_in_mb: (stats[:heap_length] * (2 << 13)).to_f / (2 << 19), | |
heaps_to_allocate_next_gc: stats[:heap_increment], | |
live_objects: stats[:heap_live_num] || stats[:heap_live_slot], | |
allocated_minus_freed_since_boot: stats[:total_allocated_object] - stats[:total_freed_object], | |
total_objects_allocated_since_boot: stats[:total_allocated_object], | |
total_objects_freed_since_boot: stats[:total_freed_object], | |
total_gc_runs: stats[:count], | |
} | |
if RUBY_VERSION !~ /^2\.1/ | |
report.merge!( | |
'RUBY_GC_MALLOC_LIMIT in mb' => (stats[:malloc_limit] ? stats[:malloc_limit].to_f : (ENV['RUBY_GC_MALLOC_LIMIT'] || 8000000).to_f) / (2 << 19), | |
'RUBY_HEAP_MIN_SLOTS' => (ENV['RUBY_HEAP_MIN_SLOTS'] || 10000).to_i, | |
'RUBY_FREE_MIN' => (ENV['RUBY_FREE_MIN'] || 4096).to_i, | |
magic_set_heaps_increment: "heaps_used * 1.8", | |
magic_before_gc_sweep_do_heap_free: "(heaps_used * HEAP_OBJ_LIMIT) * 0.65", | |
magic_before_gc_sweep_free_min: "(heaps_used * HEAP_OBJ_LIMIT) * 0.2", | |
) | |
else | |
report.merge!( | |
major_gc_count: stats[:major_gc_count], | |
minor_gc_count: stats[:minor_gc_count], | |
remembered_shady_object: stats[:remembered_shady_object], | |
remembered_shady_object_limit: stats[:remembered_shady_object_limit], | |
total_heaps_allocated_for_eden: stats[:heap_eden_page_length], | |
total_heaps_allocated_for_tomb: stats[:heap_tomb_page_length], | |
'RUBY_GC_HEAP_INIT_SLOTS (ex RUBY_HEAP_MIN_SLOTS)' => (ENV['RUBY_GC_HEAP_INIT_SLOTS'] || 10000).to_i, | |
'RUBY_GC_HEAP_FREE_SLOTS (ex RUBY_FREE_MIN)' => (ENV['RUBY_GC_HEAP_FREE_SLOTS'] || 4096).to_i, | |
'RUBY_GC_HEAP_GROWTH_FACTOR' => (ENV['RUBY_GC_HEAP_GROWTH_FACTOR'] || 1.8), | |
'RUBY_GC_HEAP_GROWTH_MAX_SLOTS' => (ENV['RUBY_GC_HEAP_GROWTH_MAX_SLOTS'] || 0), | |
'RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR' => (ENV['RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR'] || 2.0), | |
'RUBY_GC_MALLOC_LIMIT in mb' => (ENV['RUBY_GC_MALLOC_LIMIT'] || 16777216).to_f / (2 << 19), | |
'RUBY_GC_MALLOC_LIMIT_MAX in mb' => (ENV['RUBY_GC_MALLOC_LIMIT_MAX'] || 33554432).to_f / (2 << 19), | |
'RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR' => (ENV['RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR'] || 1.4), | |
malloc_limit: stats[:malloc_limit].to_f / (2 << 19), | |
malloc_increase_since_last_minor_gc: stats[:malloc_increase].to_f / (2 << 19), | |
'RUBY_GC_OLDMALLOC_LIMIT in mb' => (ENV['RUBY_GC_OLDMALLOC_LIMIT'] || 16777216).to_f / (2 << 19), | |
'RUBY_GC_MALLOC_LIMIT_MAX in mb' => (ENV['RUBY_GC_MALLOC_LIMIT_MAX'] || 134217728).to_f / (2 << 19), | |
'RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR' => (ENV['RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR'] || 1.2), | |
oldmalloc_limit: stats[:oldmalloc_limit].to_f / (2 << 19), | |
malloc_increase_since_last_major_gc: stats[:oldmalloc_increase].to_f / (2 << 19) | |
) | |
end | |
report | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment