5 ms·
> garbage collection pauses make masters “disappear” This happens only with piles of Java crap (gigabytes of jars). With [mostly] functional Erlang, Common Lis
by dschiptsov 10y ago
> garbage collection pauses make masters “disappear”
This happens only with piles of Java crap (gigabytes of jars). With [mostly] functional Erlang, Common Lisp, Haskell everything is fine.
- erpellan 10y agoAll of the languages you mentioned have garbage collectors.
- eropple 10y agoYup, and all of them have demonstrable edge cases where the GC will throw a rod. The random slagging of the most advanced virtual machine technology out there that doesn't cost four-plus digits is pretty funny, though.
- catwell 10y agoThe issue is not really the VM, it's the language. GC performance is somehow tied to the number of objects it has to deal with. Java code tends to be object-oriented and create a lot of objects. Functional code can create significantly fewer objects, so even though the Java world has the best GCs (like Azul C4) those other languages typically give their GCs less work to do. That also means that if you write code that does give a lot of work to the GC in a functional language it can certainly perform very poorly as well. Erlang is probably different, afaik creating lots of (lightweight) processes is frequent in Erlang. I don't know how the Erlang GC works so I can't really comment on that.
- qohen 10y agoI don't know how the Erlang GC works so I can't really comment on that If you're interested, here are a few helpful blogposts on the subject: - This is a pretty short and readable post, though it's a bit old (2008): "Garbage Collection in Erlang" [0] - A more detailed (and recent -- 2015) blogpost: "Erlang Garbage Collection Details and Why It Matters" [1]. - And this is the most up-to-date description, from April 2016 concerning Erlang R19, by Lukas Larsson, who works on the Erlang VM -- it is long, but well-written and has nice illustrations [2]. [0] http://prog21.dadgum.com/16.html http://prog21.dadgum.com/16.html [1] https://hamidreza-s.github.io/erlang%20garbage%20collection%20memory%20layout%20soft%20realtime/2015/08/24/erlang-garbage-collection-details-and-why-it-matters.html https://hamidreza-s.github.io/erlang%20garbage%20collection%... [2] https://www.erlang-solutions.com/blog/erlang-19-0-garbage-collector.html https://www.erlang-solutions.com/blog/erlang-19-0-garbage-co...
- qohen 10y agoOr, if you don't want to chase those blogposts down, here's the nutshell version, from reference [1]: In order to explain current default Erlang’s GC mechanism concisely we can say; it is a Generational Copying garbage collection that runs inside each Erlang process private heap independently, and also a Reference Counting garbage collection occurs for global shared heap. (To expand on that a little: each process has its own copy of everything that it needs -- if it needs something from another process, it'll get a copy in a message sent to its mailbox, so: no shared memory, links, etc. This encapsulation means that when a process terminates, all its memory is instantly reclaimed -- no GC is required, since no other process can possibly be referencing any data in the process that's going away. And, while a process is alive, there's per-process generational-copying GC, as mentioned. However, for pragmatic reasons, items > 64 bytes are stored in a global heap and references to those items are passed used (i.e. to avoid sending large things around) -- that's where the ref-counting GC comes in).
- dschiptsov 10y agoYes, this strong process isolation is one of the design decisions which leads to the ultimate success of Erlang/OTP as a telecom platform. Joe Armstrong's thesis has explicit explanation why JVM is not suitable for telecom-grade reliability (no matter what sales people would tell you). Another principal design decision, which complements share-nothing architecture, is a pure functional language with single "assignment". This greatly simplified runtime and VM itself which leads to more controlled and predictable behavior, suitable for soft-realtime systems. The concept of drivers is another one, but it is irrelevant to this discussion.
- catwell 10y agoThank you for the explanation. I will read the links as well. Even if I don't use it, the design of Erlang is an interesting topic to study.
- chrisseaton 10y agoHow does functional programming lead to generally fewer objects allocated? I would guess that it leads to more, because functional data structures require allocation to make changes where imperative programming can make destructive updates without allocating. Many functional languages allow imperative parts of course, but even in that case how is it less than the object oriented approach rather than just the same?
- pjmlp 10y agoGut feeling, not sure how much this holds. The majority of functional languages support value types (in the stack/global sense), which many OO languages that follow Smalltalk don't. Also escape analysis tends to be relatively weak in most JVM implementations (maybe Graal is the exception here). Immutable data makes it easier to collect garbage when moving living data between nurseries, thus leading to shorter pauses as in imperative languages. EDIT: Updated the sentence about escape analysis.
- chrisseaton 10y agoI think as you say immutability is probably the real benefit of functional for GCs as it simplifies a lot. But that doesn't reduce the number of objects allocated, which was the claim made.
- catnaroek 10y agoThe directed graph of immutable objects and links between them is by necessity a DAG. Only mutation can introduce cycles. If 90-95% of your objects are immutable, your GC algorithm can be specifically optimized for them. For instance, the mark and compact phases could run concurrently (interleaved) and in-place. (Yes, this means that, from a GC implementor's POV, a lazy language like Haskell mutates like crazy.)
- notacoward 10y agoIt seems to me that objects are being copied no matter what. In one world, mutation is common and the copying occurs within the GC subsystem. In the other world, mutation is rare and the programmer has to manage the copies manually. Pretending that the copies are wholly new objects which owe nothing to their predecessors strikes me as disingenuous. For all practical purposes, creating a new object that differs from its predecessor in one field is equivalent to mutating that field (except that it's far worse for performance). Is moving a burden from the runtime to the programmer a good idea? Generally, no. There might be something about this particular case that makes it an exception to the general rule, but the point seems very far from proven.
- catnaroek 10y ago> Functional code can create significantly fewer objects Functional programs, if anything, tend to create more objects than object-oriented ones. However: (0) Objects tend to be shorter lived, because new versions of data structures will be written to new objects, rather than overwritten to old objects. (1) Because functional programming deemphasizes object identities, the GC can duplicate or deduplicate objects with equal contents. It can even merge several nodes of a linked data structure into a single fat node, improving locality of reference. If object identities matter, these “optimizations” actually break your program. (2) The invariant that old immutable objects can't point to newer ones (at least in a strict functional language, not a lazy one like Haskell) can be used to optimize the GC algorithm as well.
- marcosdumay 10y ago> Functional code can create significantly fewer objects Immutability means the number of individual objects explodes. It also means those are easier to garbage collect, so you can have several different algorithms acting on different time-frames, alleviating the problem for the slower ones.
- pjmlp 10y agoHowever languages that have both GC and value types, do happen to behave better than Java, at least until Java 10 eventually makes value types a reality on the JVM. Taking something like Eiffel or Modula-3 as examples, many others are possible, architectures just like in C++ are perfectly approachable. Not doing so is just a consequence of developers that are trigger-happy with new and don't think about designing for performance.
- mSparks 10y agocare to point me to a robust in production distributed system written in one of those other languages?
- erpellan 10y agoMnesia? http://erlang.org/doc/man/mnesia.html http://erlang.org/doc/man/mnesia.html
- catwell 10y agoWell, for Erlang it's pretty easy. Also including WhatsApp servers, Riak, a lot of router code... The question is still interesting for the other two languages though.
- mSparks 10y agosystem. not database. something like boinc for example. i.e. something doing decent math rather than just reading and writing chunks of data. since erlang is up to 100 times slower than java for calculation tasks. thats 100 times more expensive in terms of hardware. so i doubt its used much for distributed systems. But i can see the confusion. Others I've simply never even considered would be chosen.
- girvo 10y agoFor Common Lisp, ITA Software[0] is a good answer, I would think. [0] https://en.wikipedia.org/wiki/ITA_Software https://en.wikipedia.org/wiki/ITA_Software
- draven 10y agoI don't know how distributed ITA software's QPX is, but there are some information about how they work around the GC in some cases here (from 2001): http://paulgraham.com/carl.html http://paulgraham.com/carl.html
- dschiptsov 10y ago
- deleted 10y ago[deleted]
- bogomipz 10y agoI think its worth noting that it isn't only Java-based distributed systems that have masters disappear. This also happens during high IO wait when heartbeats aren't received in time. Example - Mongodb which doesn't use Java at all.