# Debugging hidden memory leaks in Ruby

DevFeed: [Debugging hidden memory leaks in Ruby](<https://devfeed.tech/articles/debugging-hidden-memory-leaks-in-ruby-22435.md>)

Original publisher: [Read original article](<https://samsaffron.com/archive/2019/10/08/debugging-unmanaged-and-hidden-memory-leaks-in-ruby>)

Author: Sam Saffron

Published: 2019-10-15T05:18:18Z

Content type: tutorial

Language: en

Sources: [Sam Saffron](<https://devfeed.tech/sources/sam-saffron.md>)

Topics: [Memory Leaks](<https://devfeed.tech/topics/memory-leaks.md>), [Ruby](<https://devfeed.tech/topics/ruby.md>), [debugging](<https://devfeed.tech/topics/debugging.md>), [Tooling](<https://devfeed.tech/topics/tooling.md>)

Tags: [blog](<https://devfeed.tech/tags/blog.md>), [c-sharp](<https://devfeed.tech/tags/c-sharp.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [memory-leaks](<https://devfeed.tech/tags/memory-leaks.md>), [net](<https://devfeed.tech/tags/net.md>), [pointers](<https://devfeed.tech/tags/pointers.md>), [rails](<https://devfeed.tech/tags/rails.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [saffron](<https://devfeed.tech/tags/saffron.md>), [sam](<https://devfeed.tech/tags/sam.md>), [sql](<https://devfeed.tech/tags/sql.md>), [tooling](<https://devfeed.tech/tags/tooling.md>), [weblog](<https://devfeed.tech/tags/weblog.md>)

## AI overview

A tutorial on diagnosing unmanaged and hidden memory leaks in Ruby. It explains how a program can consume substantially more RSS than Ruby's ObjectSpace reports, then presents mwrap and related tools for tracing allocations and identifying leak sources.

## Source excerpt

In 2015 I wrote about some of the tooling Ruby provides for diagnosing managed memory leaks. The article mostly focused on the easy managed leaks. This article covers tools and tricks you can use to attack leaks that you can not easily introspect in Ruby. In particular I will discuss mwrap, heaptrack, iseq_collector and chap. image1787x742 230 KB An unmanaged memory leak This little program leaks memory by calling malloc directly. It starts off consuming 16MB and finishes off consuming 118MB of RSS. The code allocates 100k blocks of 1024 bytes and de-allocates 50 thousand of them. require 'fiddle' require 'objspace' def usage rss = `ps -p #{Process.pid} -o rss -h`.strip.to_i * 1024 puts "RSS: #{rss / 1024} ObjectSpace size #{ObjectSpace.memsize_of_all / 1024}" end def leak_memory pointers = [] 100_000.times do i = Fiddle.malloc(1024) pointers << i end 50_000.times do Fiddle.free(pointers.pop) end end usage # RSS: 16044 ObjectSpace size 2817 leak_memory usage # RSS: 118296 ObjectSpace size 3374 Even though our RSS is 118MB, our Ruby object space is only aware of 3MB, introspection wise we have very little visibility of this very large memory leak. A real world example of such a leak is documented by Oleg Dashevskii, it is an excellent article worth reading. Enter Mwrap Mwrap is a memory profiler for Ruby that keeps track of all allocations by intercepting malloc and family calls. It does so by intercepting the real calls that allocate and free memory using LD_PRELOAD. It uses liburcu for bookkeeping and is able to keep track of allocation and de-allocation counts per call-site for both C code and Ruby. It is reasonably lightweight and will approximately double the RSS for the program being profiled and approximately halve the speed. It differs from many other libraries in that it is very lightweight and Ruby aware. It track locations in Ruby files and is not limited to C level backtrackes valgrind+masif and similar profilers show. This makes isolating actual sources