Who takes out your trash?
January 22nd WeTransfer hosted the Amsterdam.rb Ruby meetup in their gorgeous new HQ. I'll try and recap the talks by Rain Leander, Technical Program Manager for OpenStack at Red Hat, and Sanne Kalkman, former teacher turned software engineer.
The life-changing magic of garbage collection
In our daily development lives, most of us don’t have to worry about unused objects gathering digital cobwebs and filling up memory space. We're comfortable knowing our programming language of choice has a garbage collector that periodically cleans up our trash.
Going all Marie Kondo on us, Sanne likens a new project to a new house you've just moved in to. "If you don't tidy, over time your place will overflow with unused items." Until recently garbage collection seemed inexplicable, but "magic is just (computer) science you don't understand yet". In its essence, gc is the tail bit of allocating memory, finding out what's garbage, and freeing up space.
Sanne's talk explores some of the more common garbage collection algorithms. Reference counting, for instance, can be explained as follows: if nothing's pointing to it, nothing depends on it. Mark & sweep - if you can't get to it, you don't need it - is about finding out what is not-trash and deleting the rest, instead of the other way around.
Copying collection will copy all objects it can get to from the 'FROM Space' to the 'TO Space', making the TO space the new FROM Space after the former is cleared out. While effective, copying collection forces you to collect twice as often, or you'll need twice the amount of memory.
So what about Ruby? MRI's garbage collection manages free memory (spots) in a 'free list'. Each slot is 40 bytes, and you fill slots until you run out of space. Ruby's garbage collector will mark and sweep, until all that is garbage collected moves back to the 'free list'. Nothing gets a new memory address though, there's no actual mobility.
Some may remember the lazy sweeping algorithm introduced in Ruby 1.9.3. From 2.1 onwards 'generational collection' - if you've been using it for a while, it's prolly important - was introduced. With generational collection, new objects are 'promoted' to old objects. Where an old object == an object that went through gc once. You usually don't collect old objects until you do a full gc because you ran out of memory.
Generational collection opened up a whole new can of worms, because what if you create a new object you can only access from an old-generation object? C certainly doens't care about your write barriers. In comes 'restricted generational collection', and sunny vs shady objects. With the latter we mean objects touched by C code, of which we can't be sure whether it points to something young / safe. Trade-offs aside, generational collecting sped up Ruby's garbage collector.
Ruby on RHEL
Rain joined us from Groningen, making a quick stop in Amsterdam on her way to the Red Hat sponsored FLOSS community conference Devconf CZ in Brno.
Documentation for using Ruby with either RHEL (Red Hat Enterprise Linux) or CentOS could be better, and Rain encourages us to improve on the onboarding instructions through contributing upstream. The message is loud and clear: it's on us to make Ruby a first class citizen for Red Hat Linux distros, and to up the supported Ruby version. "You may be able to use 2.3 using a software collection, and Red Hat's extras repository and devel directory might actually test against 2.5, but for security and stability reasons you can't use over 2.0 as a regular user."* And before you utter "but Docker?!", RHEL 7 supports Docker, but v8 doesn't (instead using Podman and Buildah).
So if your (Big) Corp uses Red Hat Linux so they can sleep at night knowing they pay for excellent support, and you want to use the bleeding edge of Ruby, you know what to do...
Next month's Amsterdam Ruby meetup will feature Michel Martens, maintainer of the Cuba framework for Ruby, and our very own Hongli Lai about the "malloc arena fragmentation problem" in Ruby (we'll just pretend we know whatever that means).
* Which is ironic, Ruby 2.0 has been EOL since 2016.