Somewhat simplified, valgrind is a virtual cpu that executes your code. While this slows down execution, it allows to check for bugs and gather statistics.
Here I describe how to use it for memory profiling.
sudo apt install valgrind massif-visualizer
Generate heap profile:
valgrind --tool=massif your_executable [your_arguments]
This runs the executable and writes a memory profile to the file massif.out.[pid]. According to the project page the profiling slows the execution with a factor of ~20x.
There are two options to examine the profile:
ms_print massif.out.[pid]
massif-visualizer massif.out.[pid]
For anything but a very small project, the console output is overwhelming, so I’d recommend the GUI visualization for anything but a quick glance (or scripts, of course)