Skip to content

Instantly share code, notes, and snippets.

@fourseven
Created September 21, 2015 05:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fourseven/ec1ec324061244aa8a5e to your computer and use it in GitHub Desktop.
Save fourseven/ec1ec324061244aa8a5e to your computer and use it in GitHub Desktop.

Preface:

It's useful to know the memory characteristics of different Ruby versions.

2.0 Uses less memory, but is slower - GC blocks while running

2.1 Generational GC - more memory, but faster GC meaning faster apps (split: old / young heap spaces)

2.2 Introduces incremental GC - marks in steps, reducing stop-the-world time, making OOB GC redundant.

See here for some more reading -

2.1 http://tmm1.net/ruby21-rgengc/

2.2 http://engineering.heroku.com/blogs/2015-02-04-incremental-gc

We could run one extra instance of a passenger worker on a 1gb Heroku dyno in 2.0, but needed it for the same throughput.

  1. If you're running multiple processes (Unicorn, Passenger), you can see the memory usage per process. With shell access this is easy, otherwise (on Passenger) - https://status-service.phusionpassenger.com/

  2. Know what your cold-memory size is, and which gems are sizeable - https://github.com/schneems/derailed_benchmarks - this needs Ruby 2.1 or higher bundle exec derailed bundle:mem

  3. Log params in production, and ensure you can tie it back to a process, which will isolate anything with leaks or large allocations. Also useful - https://devcenter.heroku.com/articles/log-runtime-metrics

  4. If you have a leak, the tooling is getting better, but re-writing it in Java is probably quicker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment