How we decreased our memory usage with jemalloc
rhymes
Posted on June 5, 2020
DEV is a Ruby on Rails application deployed on Heroku servers.
The other day Molly Struve, our resident SRE sorceress, noticed we were having some memory troubles. They didn't look like memory leaks, since they plateaued over time. But they were obviously worth investigating.
After investigating a bit I remembered how in the past I happened to switch a Rails app from the standard memory allocator to jemalloc.
The jemalloc library is an alternative memory allocator that can be used by apps (Redis ships with it) which works better with memory fragmentation in a multithreading environment.
We researched that, activated it and this was the result:
The slight decrease you see before the red bar is due to deployments which for obvious reasons free some occupied memory.
How do I do the same in my Rails app(s)?
The prerequisite is that you're using multiple threads with Rails, otherwise it won't help much.
If you're using Heroku you can follow these instructions.
If not, you can take inspiration from this tutorial and recompile your Ruby and activate jemalloc
support.
Why does this happen?
Nate Berkopec has an extensive explanation in his post Malloc Can Double Multi-threaded Ruby Program Memory Usage but long story short: the Ruby virtual machine and the default memory allocator (malloc
) aren't great at talking to each other when multithreading is involved because of the way they are both designed.
Are there any downsides?
Potentially yes, as it would make your app less portable (it doesn't work on Windows) and there are options with a smaller footprint that are being explored by Ruby core, like using malloc_trim().
My suggestion is to test it :-)
Posted on June 5, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.