Do Out-of-Band Garbage Collection

Despite all our optimization efforts, GC will continue to take a substantial part of execution time. So what do we do if we can’t reduce GC time? We force GC when our application isn’t doing anything. That approach is called Out-of-Band Garbage Collection (OOBGC).

Idle time is something that we usually observe in web applications and services. So let me show you how to configure OOBGC for the most popular Ruby web servers.

Example: OOBGC with Unicorn

Unicorn[35] has direct support for OOBGC.

If you use Ruby 2.1 or later, add the gctools gem[36] to your Gemfile and put this into your config.ru for Unicorn:

 
require ​'gctools/oobgc'
 
use(GC::OOB::UnicornMiddleware)

When does the OOBGC happen? You might guess it should run after every N requests. But that would add unnecessary load to your server. Not all requests are the same, and some of them might leave little to no garbage.

The gctools library does it in a better way. Ruby 2.1 exposes enough information about its internal state for the gctools to decide when the collection is required. You can read more about how it works, and what results to expect, in its author’s blog.[37]

However, if you’re still using Ruby version 2.0 and lower, then the only OOBGC strategy is to force GC after every N requests. Unicorn has the built-in middleware for that:

 
require ​'unicorn/oob_gc'
 
use(Unicorn::OobGC, 1)

Here the second parameter to the use() call is the frequency of OOBGC: 1 means after every request, 2 means after every two requests, and so on.

Example: OOBGC in Other Web Servers or Applications

We can use the gctools library to do OOBGC in any code. Once we determine when our code has idle time, we can call this:

 
require ​'gctools/oobgc'
 
GC::OOB.run

There are two things to keep in mind when implementing OOBGC on your own.

First, make sure that you get your OOBGC timing right. For web applications, it’s after the request body is flushed into the stream. For background workers, it’s after finishing the task and before pulling the next task from the queue.

Second, be careful if you use threads. If you force GC from one thread while the other is still doing its job, you will block that other thread. So you should make sure all threads in the process are doing nothing before calling OOBGC.

That’s why, for example, the Puma web server doesn’t support OOBGC. Unlike Unicorn, Puma’s workers can be multithreaded, and there’s no single point in time when you can safely perform OOBGC.

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

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