Interesting to see in this article how an unpredictable Garbage Collector can make things very bad on production. This is the kind of value that BEAM brings for Elixir and Erlang users.
Go takes a different approach, collect very conservatively in order to achieve low latencies, but this means that under heavy load memory use runs up, sometimes out of control.
In BEAM the GC can work differently to the JVM or other languages. The main difference is that BEAM uses per-process stack, and by generational principle - most of the processes are short-lived (especially in Phoenix applications and similar). Also (almost) all data is copied between processes on message. That mean that main GC for Erlang can be simple per-process arena that can be cleaned all when process dies as you will not free data “shared” between different processes. In Java where you have mutability and you share data between processes/threads such “optimization” would be impossible.