Tune Up GC Settings

We can change some of Ruby GC parameters with environment variables. Let’s see what’s available.

Ruby 2.1, 2.2, and Later

RUBY_GC_HEAP_INIT_SLOTS

Initial number of object slots on the Ruby heap. Default value is 10000.

You might want to change this number if you know that your application will allocate lots of objects right from the start.

But on the other hand, we saw that Ruby is quite good at growing the heap space. It usually grows faster than we need. So there’s little need to change this parameter in practice.

RUBY_GC_HEAP_FREE_SLOTS

Minimum number of free slots that must be free after GC. If this condition is not met, Ruby might grow the heap space. Default value is 4096.

As we discussed in GC Triggered by Heap Usage, the heap growth rule is more complicated. This value is used only once at runtime during the first heap growth after the initial one. So there’s absolutely no need to change it.

RUBY_GC_HEAP_GROWTH_FACTOR

Heap growth factor. Default value is 1.8.

Ruby is already aggressive enough at heap growth, so you should not increase this number. Decreasing it also makes little sense. Heaps are allocated on demand in modern interpreters, so decreasing this number will not reduce the total memory consumption.

RUBY_GC_HEAP_GROWTH_MAX_SLOTS

Maximum number of slots Ruby can add to the heap space at a time. The default value is 0, meaning that there’s no maximum.

If your application needs to allocate millions of objects during its lifetime, you might want to cap the heap growth increments by setting this value.

However, it will not help to reduce the GC time for such an application. Ruby is not the right tool to process lots of objects, and you should consider using other tools rather than trying to tweak Ruby.

RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR

This forces Ruby to do major GC when the number of old objects is more than RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR * <number of old objects after the last full GC>. The default value is 2.0.

In theory, you might want to increase this number if you expect that too many of your objects will become unused after getting into the old generation (surviving one GC in Ruby 2.1 and three in Ruby 2.2).

In practice, this is very rarely needed, and the default setting is good enough for most people.

RUBY_GC_MALLOC_LIMIT, RUBY_GC_MALLOC_LIMIT_MAX, RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR

Minimum and maximum malloc limits for the new generation, and the limit’s growth factor. The default values are 16 MB minimum, 32 MB maximum, 1.4 growth factor.

These are the parameters you might want to change. If your application uses more memory than average, then increase the minimum and maximum values. If your application allocates memory in chunks, consider increasing the growth factor. There’s little sense in decreasing these values.

You might find advice on the Internet to set the minimum limit to 64 MB, or even 128 MB (that Twitter used at some point). But be careful. Larger limits lead to higher peak memory consumption.

Increase the limits incrementally, adding, for example, 8 MB at a time, and measuring the outcome. Be even more careful changing the growth factor.

I personally find that these days 50% of applications run just fine with the default settings, and another 50% benefit from a two times increase of minimum and maximum limits.

RUBY_GC_OLDMALLOC_LIMIT, RUBY_GC_OLDMALLOC_LIMIT_MAX, RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR

Minimum and maximum malloc limits for the old generation, and the limit’s growth factor. The default values are 16 MB minimum, 128 MB maximum, 1.2 growth factor.

These are also candidates for tweaking. It’s a good idea to change them together with the limits for new generation, and in the same manner.

Ruby 2.0, 1.9, and Earlier

Older Ruby versions require recompilation to change all their settings except these three:

RUBY_HEAP_MIN_SLOTS

Same as RUBY_GC_HEAP_INIT_SLOTS in newer Ruby.

RUBY_FREE_MIN

Same as RUBY_GC_HEAP_FREE_SLOTS in newer Ruby.

RUBY_GC_MALLOC_LIMIT

One malloc limit for non-generational GC. The default value is 8,000,000 bytes.

You absolutely must change this value. 8 MB limit is too small, and will lead to more GC runs than necessary. Increase it to at least 16 MB. Then, continue adding 8 MB and testing the outcomes until you find your sweet spot.

There’s no way to change GC parameters without recompilation in Ruby 1.8. If you still use that version, consider switching to the more configurable Ruby Enterprise Edition.[42] Just like Ruby 1.9 and 2.0, Ruby 1.8 needs a larger malloc limit for better performance.

Let’s quickly review. The only parameter that makes a difference in performance is the malloc limit. You must change it for older Ruby versions, and consider a slight increase for newer versions. Other parameters have either good default values for most cases, or make no sense to change.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.106.233