←back to thread

175 points nateb2022 | 1 comments | | HN request time: 0.205s | source
Show context
nahuel0x ◴[] No.41522944[source]
Three big differences in comparison with Erlang: 1- Cannot externally kill a process (yes, ergo process have a Kill method but the process will be in a "zombie" state until the current message handlers returns... maybe stuck forever) 2- No hot code reloading. 3- No per-process GC.
replies(4): >>41523113 #>>41523543 #>>41524544 #>>41525115 #
throwaway894345 ◴[] No.41523543[source]
I've never written any Erlang before--why do I care about per-process GC?
replies(5): >>41523595 #>>41523906 #>>41523962 #>>41524224 #>>41527473 #
davisp ◴[] No.41523962[source]
Also, for anyone not completely familiar with Erlang's terminology, the translation of "per process garbage collection" to Go would be "per goroutine garbage collection". As mentioned in a sibling comment, this allows Erlang style garbage collection to avoid pausing the entire operating system process when running garbage collectin.
replies(1): >>41524107 #
whizzter ◴[] No.41524107[source]
Per-process GC is an optimization similar to nurseries in regular collectors, esp any object that has been sent in a message must be visible globally (yes there could be small object optimizations but that would increase sender complexity).

Also an overlooked part here is that the global Erlang GC is easier to parallellize and/or keep incremental since it won't have object cycles sans PID's (that probably have special handling anyhow).

TlDr; GC's become way harder as soon as you have cyclic objects, Erlang avoids it and thus parts of it being good is more about Erlang being "simple".

replies(3): >>41524336 #>>41524534 #>>41524592 #
1. toast0 ◴[] No.41524534[source]
Erlang avoids object cycles because it's impossible to make an old term point to a new one; data is immutable, so new terms can only referenece previous terms. This means the GC doesn't have to consider cycles and keeps things simple.

But that's separate from per process GC. Per process GC is possible because processes don't share memory[1], so each process can compact its own memory without coordination with other processes. GC becomes stop the process, not stop the world, and it's effectively preemptable, so one process doing a lot of GC will not block other processes from getting cpu time.

Also, per process GC enables a pattern where a well tuned short lived process is spawned to do some work, then die, and all its garbage can be thrown away without a complex collection. With shared GC, it can be harder to avoid the impact of short lived tasks on the overall system.

[1] yes yes, shared refcounted binaries, which are allocated separately from process memory.