[erlang-questions] Why intra-node messages are copied and not refcounted, rationale?
Fri Jun 5 04:34:20 CEST 2015
With refcounting you can easily make an implementation where freeing large
structure does not block the system, you do it in small chunks. I think a
much worse problem is that in a multi-core/threaded environment if you want
to GC shared state you must synchronize and lock data while you are working
and this is very expensive. When you GC process heaps separately you can
On 7 May 2015 at 10:27, Jesper Louis Andersen <
> On Thu, May 7, 2015 at 3:07 PM, Nahuel Greco <> wrote:
>> What's the rationale of accepting a copying cpu/memory overhead? Why a
>> refcounting mechanism like the used for binaries is not desirable for all
>> the data structures?
> Really good questions!
> Why copy and not pass by reference? It is implementation specific, as the
> Erlang language allows for both semantics, and there were a variant of the
> VM which used varying reference-passing tricks in place of the current
> copying solution. The biggest disadvantage is that if you send very large
> messages, then the copying overhead is large and costs performance. But
> there are also some important advantages to copying. Each process can have
> its own heap arena for instance, so this breaks up the memory space into
> many small chunks which can be individually garbage collected. Erlang is a
> soft realtime system, so you can't afford long garbage collection pauses.
> This is usually really good for GC pause times as they can be quite small.
> The second big advantage is that the semantics are the same for local
> processes as well as distributed processes. You *have* to copy if the
> process lives on another node anyway. The third advantage is that data
> becomes local to a process, and thus local to a processing core. There are
> advantages to this model on a system where memory access is highly
> non-uniform, because you can in theory pick memory close to the processing
> As an example, I have been brewing on some latency benchmarks for
> webservers. A sneak peak is the median response time of this test:
> out.go: 50.000% 1.72ms
> out.undertow: 50.000% 1.53ms
> out.cowboy: 50.000% 6.33ms
> where clearly, Erlang is far slower than a Go or Undertow, a Java-based
> webserver. But once we look at the 99.99th percentile, things are different:
> out.go: 99.990% 58.75ms
> out.undertow: 99.990% 47.90ms
> out.cowboy: 99.990% 38.62ms
> and at the 99.999th percentile it gets really funny:
> out.go: 99.999% 216.45ms
> out.undertow: 99.999% 64.61ms
> out.cowboy: 99.999% 45.09ms
> what you see here is garbage collection overhead because you have such
> large heaps to traverse, or that there are some other factor imposing
> additional latency for a few of the calls.
> Why not use refcounting? One price of refcounting is unpredictable
> performance. If you ref-count a large list and free it up, then the GC has
> to get rid of this list, and it will take quite some time. Many refcounting
> GC's runs this as a background job to handle this. In fact, Refcounting GCs
> are dual to Mark&Sweep GCs. In the binary heap, a binary can contain no
> pointers, which means reclamation of memory is always constant.
> Furthermore, without optimizations, refcounting GCs tend to perform badly.
> With optimizations, they start to look like Mark&Sweep collectors, as
> written in .
> In other words, both decisions are design decisions which tend to yield
> good soft realtime performance on current hardware, and predictable
> performance, especially in the worst case. You may not want a system that
> stalls for at least 216ms every 100.000th call. But there are no rules in
> the Erlang semantics which constrains us from coming up with another
> message passing scheme, should we invent one that is even better. It is
> just that the current behavior is highly desirable in the systems where
> Erlang tend to get used.
> erlang-questions mailing list
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the erlang-questions