Counting live objects in Ruby

There are cases, when you have discovered a memory leak, you have a pretty good hunch about what it is that is being leaked, or you have at least narrowed it down to a few candidates.

When this is the case, a full blown profiler can often seem to be too big a tool to start wielding.

Fortunately Ruby offers a way to peek at what is happening. The module ObjectSpace contains some methods that can give some insights.

Perhaps the most interesting method is this situation is ObjectSpace#each_object.

What it does is when given a block it is iterating over either all live objects or just the live objects that match or are a subclass of a certain module. Without a block, it returns an Enumerator.

And at this point it starts to get interesting, because this Enumerator is countable.

By using that it requires very little effort to start collecting number of live objects of different types.

I’ve quickly put together a little method that can collect the difference of the number of live objects before and after executing a block of code:

What it does is it simply returns a hash containing the before and after counts of each of the classes given.

I.e. would the following:

foo = nil
Allocations.delta_of ::String do
  foo = 'bar'

result in the hash { :String => { :before => 0, :after => 1 } } being returned.

This is pretty basic stuff, and it is almost definitely only just enough to confirm hunches. Furthermore it is only useful in the case where you have an idea of which classes or modules that are being leaked.

Please also note that this isn’t made to be fast. If you happen to have large amounts of objects of the types you’re trying to measure on, you could risk that your code grinds to a halt. And it is by no means intended to be used in any production environment (unless you’re willing to take the risk that it could result in downtime).