This piece of advice is also valid in languages without GC. In C++ it's well known one should avoid allocating memory in tight loops, and it's strongly advised to call e.g. `reserve` on vectors to avoid allocating.
free() as well as malloc() and related have significantly complex algorithms behind them, unless one can simplify base memory management in certain ways - and those ways tend to also allow region-enabled GC to outperform them anyway.
[1] Allocating memory in many Garbage Collected systems can be down to one instruction, and if using per-thread heap, it can be atomic add without CAS
As sibling comment says, it often involved object caches and static allocations.
Interestingly enough, similar rules are necessary with malloc()/free where dynamic allocation is often forbidden for latency critical code (or safety critical one)
I stopped complaining too much about developers when I noticed pretty much Noone gets taught how memory management works - either manual or GC