jola
Why do releases use so much more memory than `mix run`?
A question was asked here whether releases use less memory, so checked in a project I’m working on and I was surprised to see almost twice the memory use for the same code. To make sure it wasn’t just my project, I tried with a plain Phoenix app and only the minimal steps to get releases started. This is what I did if you want to reproduce:
mix phx.new hello --no-webpack --no-html --no-ecto
# added {:distillery, "~> 2.0"} to mix.exs
cd hello
mix deps.get
MIX_ENV=prod mix release
Then to compare the memory use I relied on :erlang.memory/0. First using plain mix run in iex.
MIX_ENV=prod iex -S mix run
iex(1)> :erlang.memory
[
total: 31407808,
processes: 7082192,
processes_used: 7063440,
system: 24325616,
atom: 512625,
atom_used: 504423,
binary: 97440,
code: 10298466,
ets: 929712
]
and then starting the release in the equivalent console
_build/prod/rel/hello/bin/hello console
iex(hello@127.0.0.1)1> :erlang.memory
[
total: 55362432,
processes: 14649704,
processes_used: 14363384,
system: 40712728,
atom: 984241,
atom_used: 961617,
binary: 174464,
code: 21349495,
ets: 2029176
]
Total reported memory use went from 31MB to 55MB. And you see increases across the board. In my personal project the increase was even more significant, going from 45MB to 90MB.
One thing I guess could be related is that I believe releases preload all code while mix will load modules on demand. But does that really account for the whole difference?
I also want to add a disclaimer: I’m still using releases and I don’t find the memory used to be unreasonable. This is just curiosity!
Most Liked
michalmuskala
I think the code loading part will be the major difference - more code means more atoms, more binaries (from literals in those modules) and more ets usage (since information which modules are loaded is held in an ets table by the code_server process). Additionally there might be some more system-level services running like SASL or the release handlers, which could account for the extra process size. Have you tried comparing the outputs of Process.list() on both systems? That could shed some more light on it. Similarly for ets tables you could investigate with :ets.info.
rvirding
Check to see which applications have been loaded, there may be more in the release. Also check which applications have been started. IIRC correctly the release will start all applications at start up time.
tristan
Your release is likely starting in embedded mode while mix run is interactive mode. Embedded mode will load all beam modules on start up instead of only when they are used.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










