On an intuitive level, think of swap as being a place the kernel can put memory the program has written. When you malloc(4096) and write some bytes into it, the kernel can't evict that page to disk unless there's some swap space to stick it in. However, executables are different because they're already on disk -- the in-memory version is just a cache (everything is cache (computers have too many caches)). The kernel is allowed to drop the copy of the program it has in memory, because it can always read it back from the original executable.
[0] https://man7.org/linux/man-pages/man2/mlock.2.html
[1] https://ftp.gnu.org/old-gnu/Manuals/glibc-2.2.3/html_chapter...
There are a few relevant bits to this. You can MAP_POPULATE the file to prepopulate the entries and you can MAP_LOCKED to MAP_POPULATE + lock the pages in (unreliably). As mentioned in the man page for mmap MAP_LOCKED has some failure modes that you don't get with mlock.
https://www.man7.org/linux/man-pages/man2/mmap.2.html
I also found this page: https://eklitzke.org/mlock-and-mlockall
Oh, and this: https://access.redhat.com/documentation/en-us/red_hat_enterp...