Interesting discussion:
It’s hard to say on versions built with go prior to 1.16 what’s going on since when it releases memory it uses MADV_FREE - which tells the kernel not to reclaim the memory unless the kernel needs it. The side effect of this was that container orchestrators would kill off go programs for using too much memory when in fact they are using a lot less.
In Go 1.16 they moved to MADV_DONTNEED which will immediately cause the memory to be reclaimed. Our 2.2.0 release is built using go 1.16, you might well seen an impovement by looking at that.