For years, people have been using jemalloc with ruby. There were various benchmarks and discussions. Legend had it that Jemalloc 5 didn't work as well as Jemalloc 3.
Then, one day, hope appeared on the horizon. @wjordan offered a config for Jemalloc 5.
FROM ruby:3.1.2-bullseye
RUN apt-get update ; \
apt-get install -y --no-install-recommends libjemalloc2 ;
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
ENV MALLOC_CONF='dirty_decay_ms:1000,narenas:2,background_thread:true'
FROM ruby:3.2.3-alpine3.19
RUN apk add --update jemalloc
ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2
ENV MALLOC_CONF='dirty_decay_ms:1000,narenas:2,background_thread:true'
- add the
apt buildpack,
which is maintained by Heroku.
heroku buildpacks:add --index 1 heroku-community/apt
- create an
Aptfile
with this in it, and deploy it.libjemalloc2
- Set these ENV vars:
heroku config:set \ LD_PRELOAD="/app/.apt/usr/lib/x86_64-linux-gnu/libjemalloc.so.2" \ MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true"
There is also the third-party heroku-buildpack-jemalloc, which will download, build, and install an arbitrary jemalloc version, which is useful if you need a version not distributed by Ubuntu for some reason, such as before the discovery of the improved MALLOC_CONF, necessitating the installation of version 3.6
dirty_decay_ms:1000,narenas:2,background_thread:true
comes from dockerfile-rails. code discussion- This is the original "tradeoff between memory and performance". it is likely identical to the above config
on recent Jemalloc and Ruby versions, because the extra values are the defaults
dirty_decay_ms:1000,muzzy_decay_ms:0,narenas:2,background_thread:true,thp:never
muzzy_decay
is 0 by default (MALLOC_CONF=stats_print:true ruby -e "exit"
)thp:never
is default behavior on ruby starting in 2.6 https://bugs.ruby-lang.org/issues/14705
- This is "more heavily memory-optimized, like jemalloc 3.6" (the version used by Fullstaq Ruby)
dirty_decay_ms:0,muzzy_decay_ms:0,narenas:2,background_thread:true,thp:never
- This is used by gitlab
1
2
narenas:2
MALLOC_CONF="stats_print:true" ruby -e "exit" # will produce no output if jemalloc not being used, a wall of text if it is
MALLOC_CONF="$MALLOC_CONF,stats_print:true" ruby -e "exit" # if a config is set, you can include it like this
- https://github.com/gaffneyc/heroku-buildpack-jemalloc
- https://github.com/fullstaq-ruby/server-edition#vs-ld_preloading-jemalloc-yourself
- https://news.ycombinator.com/item?id=27873579
- https://bugs.ruby-lang.org/issues/14718
- comment from jemalloc dev: https://bugs.ruby-lang.org/issues/14718#note-86
- https://github.com/code-dot-org/code-dot-org/blob/staging/cookbooks/cdo-jemalloc/attributes/default.rb
- https://github.com/zooniverse/panoptes/pull/4027/files
- https://gist.github.com/jjb/81866452fd979cae81297cb28713b4bf
- https://www.paulashraf.com/blog/jemalloc-ruby
- https://github.com/SamSaffron/allocator_bench
- https://andresakata.medium.com/benchmark-of-memory-allocators-on-a-multi-threaded-ruby-program-354ec4dc2e7e
- https://engineering.appfolio.com/appfolio-engineering/2018/2/1/benchmarking-rubys-heap-malloc-tcmalloc-jemalloc
- https://twitter.com/wgjordan/status/1440574986264006659
- fullstaq-ruby/server-edition#98
- https://github.com/jemalloc/jemalloc/blob/dev/TUNING.md
- http://jemalloc.net/jemalloc.3.html
- https://bugs.ruby-lang.org/issues/15667
- https://www.speedshop.co/2017/12/04/malloc-doubles-ruby-memory.html
- https://github.com/kaspergrubbe/grubruby-jemalloc
- discussion on adding jemalloc to official ruby docker images docker-library/ruby#182
- bonus: building jemalloc 3 from source: jemalloc/jemalloc#2394