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.
: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.
The correct environment variable name is RUBY_HEAP_MIN_SLOTS
.
https://github.com/ruby/ruby/blob/v1_9_3_194/gc.c#L441
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