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!