A tool for working with and analyzing Ruby processes' heap dumps created via
ObjectSpace.dump_all
.
Dumping the heap from a running Ruby process is not very difficult as long as
your app has required the rbtrace
gem.
- Add the
rbtrace
gem to your application, and require it in your code when the application boots. - Find the PID of your running Ruby process.
- Run the following to dump your process' heap to a file called
heap.jsonl
:rbtrace -p $PID -e 'Thread.new{GC.start;require "objspace";File.open("heap.jsonl","w"){|f|ObjectSpace.dump_all(output: f)}}'
The leak command is intended to help track down memory leaks. By requiring three heap dumps as input, it attempts to find memory that showed up in dump #2, and is still there in #3.
The idea is to take a heap dump shortly after the application starts and before it's had much of a chance to leak memory. Then take another heap dump after it's been running for a while and leaked memory. And finally take a third heap dump after it's been running for a while longer and leaked even more.
But comparing these three dumps and extracting only the objects which are held in memory during heap dumps #2 and #3, we should mostly be left with objects which are leaked memory.
Usage:
rbheap leak [flags] <dump-A> <dump-B> <dump-C>
Flags:
-f, --format string output format: "hex" / "json" (default "hex")
-h, --help help for leak
-v, --verbose print verbose information
This project is mostly based on the ideas and concepts from the following articles:
- What I Learned About Hunting Memory Leaks in Ruby 2.1 by Peter Wagenet
- How I spent two weeks hunting a memory leak in Ruby by Oleg Dashevskii
- Debugging memory leaks in Ruby by Sam Saffron