Skip to content

Instantly share code, notes, and snippets.

@akitaonrails
Created April 9, 2014 00:17
Show Gist options
  • Save akitaonrails/10212233 to your computer and use it in GitHub Desktop.
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 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