A Day in the Life of a Ruby Object, by Jemma Issroff

Abstract:

Your code creates millions of Ruby objects every day, but do you actually know what happens to these objects?

In this talk, we’ll walk through the lifespan of a Ruby object from birth to the grave: from .new to having its slot reallocated. We’ll discuss object creation, the Ruby object space, and an overview of garbage collection.

Along the way, we’ll learn how to make our apps more performant, consume less memory, and have fewer memory leaks. We’ll learn specific tips and pointers for how to see what the garbage collector is doing and how to take advantage of the strategies it employs.

Details:

One of the major benefits most developers see of writing code in a language with managed garbage collection is that, on average, we have no need to learn about the internals of garbage collection. For the most part, we can write code in Ruby blissfully unaware of what is happening underneath the hood with all of the objects we’re creating. However, there are major benefits to gaining an understanding of exactly what is happening.

Every so often, a Ruby/Rails app is performing less optimally than we want, and sometimes this has to do specifically with garbage collection or memory management. In some cases garbage collection is running too frequently, and in other cases not frequently enough. We, as developers, cannot begin to understand how to debug or solve a problem in our app related to memory management if we do not understand how garbage collection is actually working.

Furthermore, there are specific ways we can interact with garbage collection to make it work better for our apps. In some cases, this means starting major garbage collections. Some features related to memory management explicitly require us to know how garbage collection is working. Memory compaction was shipped with the Ruby 2.7 release. The caveat? Using this feature requires developers to manually run compaction.

In cases like this, it becomes a necessity for any developer working on the memory management or performance of their app to not only understand garbage collection, but also to be able to see how garbage collection is interacting with our apps, understand the nuances behind it, and see how changes (like compaction) can tangibly influence performance.

This talk will cover how to see what the garbage collector is doing at any point in the running of an app, many different strategies that Ruby’s GC uses, and how and when to turn on garbage collection to ensure it’s behaving in ways that optimize an app’s performance.

The second reason developers will be interested in this talk is pure curiosity. I anticipate that this second audience will largely be folks who fell in love with Ruby for its elegance, and are curious to see that elegance permeate into the depths of garbage collection. My goal in giving the talk is that this audience, too, will learn about garbage collection in ways that will make them better Ruby developers because they will fundamentally understand what is happening with each object creation, when they might be able to allocate fewer objects, or how to learn more about a problem if they notice spikes in memory usage or a memory leak.

This talk will take a slightly non-conventional and exciting route of teaching about garbage collection from the perspective of a Ruby object by tracking the actual journey that an object might take. By structuring the talk as a series of choices that the garbage collector makes based on the properties of an object about what to do with it, I will explain many nuances behind garbage collection--how some objects might survive rounds of garbage collection, while others might have their slots added to the free list.

Topics that I intend to touch in this talk are:
The Ruby Object Space

  • This is where references to Ruby objects live
  • Defining the Object Space and demonstrating how to visualize it are essential to understanding the effects of all of the strategies described in the rest of the talk
  • Defining slots, pages, RValues
  • These make up the crux of the object space Tri-Color Mark and Sweep Algorithm
  • This is the two-phased algorithm Ruby uses for garbage collection
  • Understanding how it works is core to developing intuition about how to utilize Ruby’s GC effectively Generational Garbage Collection (Ruby 2.1)
  • This strategy takes advantage of the principle that most objects die young
  • It splits objects into two main camps: old and new
  • Attempts to collect new objects in frequent, minor GCs, while only looking at old objects in less frequent, major gcs Incremental Garbage Collection (Ruby 2.2)
  • This strategy interleaves the mark phase with execution of Ruby code
  • Caused significant speedups in memory management
  • Ruby runs stop-the-world garbage collection, so there is a necessary cost of GC in that when it’s running, no ruby code is executing. Splitting it up incrementally allows for less interference of GC Write Barrier protected objects
  • These are fundamental to how Generational GC can work
  • Explains how when new objects have references from old objects, we ensure we don’t sweep the new objects Compaction (Ruby 2.7)
  • Compacts allocated slots onto fewer pages where possible
  • Required to toggle it on manually
  • Some objects created by C extensions do not support compaction

As just described, the outcomes are twofold. I hope to satiate developers’ curiosity through a fun description of what is actually happening literally every time they run Ruby code. And I also hope to give developers the tools they need to actually take advantage of Ruby’s garbage collection mechanisms.

Pitch:

Every Ruby/Rails developer is interfacing with garbage collection whenever they use Ruby. Yet most Ruby developers know little about the internals of what is actually happening. This gap in Ruby knowledge means that when there are issues with memory management or performance, many developers do not have the tools they need to solve them. This talk should be considered because it is peeling back the curtain of what happens within Ruby’s memory management. It is doing so in a way which will make any Rails developer better equipped to tackle memory management bugs.

I am qualified to give this talk because I am currently writing a book about managed garbage collection, with a focus on Ruby. I know firsthand where optimizations are possible for garbage collection, having worked for many years optimizing performance and memory usage in a large scale Rails app.

In addition to studying computer science, I also studied education and deeply value teaching. This is one of the reasons I am currently writing a book, and explicitly why I will be so honored and excited to give the talk; it will present an opportunity to teach at a bigger scale.

This will be my first conference talk. I have given many technical talks at my previous company and received positive reviews for my clarity, simplicity, and enthusiasm. I plan to build on the techniques and structures I have learned through these company technical talks, applying them to a wider audience. I would feel privileged to share my deep knowledge and passion for the topic with the broader Ruby/Rails community through RailsConf.

Edit proposal

Submissions

RailsConf 2021 - Accepted [Edit]

Add submission