What do the fields of Ruby's GC.stat mean?

2020-02-23 08:31发布

问题:

I am using GC.stat to profile memory usage in our Rails app. GC.stat returns a hash with the following keys:

:count
:heap_used
:heap_length
:heap_increment
:heap_live_num
:heap_free_num
:heap_final_num

Does anybody know exactly what these values mean? There's no documentation of them in the Ruby source (gc.c), just a comment: "The contents of the hash are implementation defined and may be changed in the future."

Some of these fields make sense from context, e.g. count is the number of heaps Ruby has allocated. But what is heap_final_num? What is heap_increment? Is heap_length the minimum heap size?

I'm fiddling with RUBY_MIN_HEAP_SLOTS, RUBY_FREE_MIN and RUBY_GC_MALLOC_LIMIT, but changing those env vars doesn't seem to have any effect on :heap_count or :heap_length. I would expect that :heap_count would go down if I radically increase min heap slots. So I really would like to know exactly what all the GC.stat values represent!

I'm using Ruby 1.9.3.

回答1:

:count - the number of gc cycles, e.g. how many times did gc run

:heap_used - the number of allocated heaps, ruby creates one heap by default and increase heap number if it's not enough to allocate all objects

:heap_length - the size of the heap. That's the first heap size. Ideally you should have one heap after script start

:heap_increment - the number that would be added to the last heap size if ruby creates new heap

:heap_live_num - how many heap slots are allocated

:heap_free_num - how many heap slots are free

:heap_final_num - finalizers slots number

You are right that by increasing RUBY_MIN_HEAP_SLOTS the number of heaps should decrease down to one. But the higher RUBY_FREE_MIN the more heaps you'll get. It indicates the number of free slots that current heap should have, if that number is less than you provided - ruby creates new heap. RUBY_GC_MALLOC_LIMIT is more related to how often ruby would run GC process and does not affect heaps number directly. This counter indicates after how many mallocs ruby would run GC. But it can be runed even earlier. Please note that it's not ruby obj allocations, it's global ruby internal malloc counter that's incremented on any ruby interpreter internal obj allocation.



回答2:

The correct environment variable name is RUBY_HEAP_MIN_SLOTS.

https://github.com/ruby/ruby/blob/v1_9_3_194/gc.c#L441



回答3:

It looks to me like :count is the number of 'lazy sweep' GC cycles, not full GC cycles on Ruby MRI 1.9.3p448.

I had to force a full GC before the profiler reported any GC events:

GC::Profiler.enable
GC.start
GC::Profiler.report