Garbage collection and memory

GC.stat

GC.stat is a snapshot of the collector: how many objects are alive, how many were allocated in total, how often the collector ran and how much time it used. One key answers most questions:

ruby -e 'puts GC.stat[:heap_live_slots]'

23020

A bare Ruby already holds a few thousand objects, so the number alone means little. Read it twice and look at the difference, which is the memory the work actually kept.

Live slots

The same reading before and after allocating a hundred thousand strings. The gap is the garbage collector's backlog, not just the array:

before = GC.stat[:heap_live_slots] strings = Array.new(100_000) { "x" * 10 } after = GC.stat[:heap_live_slots] p before: before, after: after

ruby gc.rb

{before: 23035, after: 126849}

The difference is about a hundred thousand slots, which is the array plus one string per entry. A loop that builds the strings and throws them away leaves the live count flat but raises total_allocated_objects, and that is the number that predicts a collection pause.

ObjectSpace

ObjectSpace.count_objects breaks the heap down by type. A string-heavy program shows it at once:

p ObjectSpace.count_objects[:T_STRING] p GC.stat[:total_allocated_objects]

ruby gc.rb

117953 235417

Nearly half of the allocations in this tiny script are strings. A real application that builds a message per request allocates a dozen strings it never shows anyone; the fix is usually to build the message only when the level is enabled.

The strings that dominate

Three patterns account for most avoidable string churn:

What to watch for

A high live count is not a leak. A leak is a count that climbs with every request and never comes down; a high constant is a cache or a big configuration. Compare two requests, not two minutes.

GC.start before a measurement forces a collection and makes the number repeatable. It also hides the cost the production process pays, so use it for a measurement and not in the code.

Next: Profiling a slow script

Article author: Arthur Isaev

Banner image