In OTP 25 and earlier you need to include the
tools application for it to be available, which is often excluded from releases, so that’s probably why (it’s been moved to
runtime_tools in OTP 26)
Looking at the source code for the
appsignal NIF I think it would be a good idea to temporarily include the
tools application to check this.
The NIF seems to allocate a tiny resource (just a pointer) for each transaction which won’t make much of a dent in
erlang:memory() unless tons of them have been allocated, but the pointed-to memory seems to be allocated using system allocators (
malloc(2) et al) which will hide it from view: what looks like a megabyte or two in
erlang:memory() might actually be hundreds.
If this is the culprit it’ll stick out like a sore thumb in the
Aside from using
instrument you can try running your test cases under valgrind, though it’ll take some editing to make it work with Elixir.
Make sure valgrind is installed, and build OTP from source with the special valgrind emulator type:
$ export ERL_TOP=`pwd`
$ export MAKEFLAGS=-j
$ ./otp_build setup -a
$ (cd erts/emulator/; make valgrind)
# Save this for later
$ readlink -f bin/cerl
Then edit your
bin/elixir script to use it, changing the following line…
set -- "$ERTS_BIN$ERL_EXEC" -noshell -elixir_root ... et cetera et cetera
set -- "the path you got from readlink" -valgrind -noshell -elixir_root ... et cetera et cetera
If all goes well, you should see something like the following starting
==607653== Memcheck, a memory error detector
==607653== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==607653== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==607653== Command: xyz
==607653== Warning: set address range perms: large range [0x521b000, 0x4521b000) (noaccess)
Erlang/OTP 27 [DEVELOPMENT] [erts-14.0] [source-5776496e72] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit] [valgrind-compiled]
Interactive Elixir (1.15.0-dev) - press Ctrl+C to exit (type h() ENTER for help)
It will run like a snail going uphill but if there’s a regular memory leak it’ll tell you all about it. Unfortunately it can’t tell you about things like a forever-expanding queue where all elements are reachable but never end up being freed, though.