It also reminded me how much I wish there was an actual specification for BEAM, finding out the details of the how the bytecodes work is an arduous task compared to the JVM where everything is explicitly stated. IMHO both VMs are excellent in their own right, the HotSpot JIT is incredible, but I still can't deny that I find the beam process model on concurrency more elegant than the JVM one, though in practice I've only toyed in erlang so I have no real-world grounds of comparison there. Does anyone by chance?
Wouldn't it be more correct to speak of the EVM as opposed to ERTS here? ERTS defines things like the boot protocol, distribution protocol, term serialization, port drivers, NIFs and BIFs. Though when talking about scheduling semantics, that's on the EVM level (to differentiate it from BEAM in particular).
I was working with Erlang for about 2 years in a multi-language environment, and we based our networking messaging infrastructure on top of the Erlang protocol. It's still there, but we're migrating from it.
One major thing that turned me off of the language for our particular project was that there was no way to have a large read-only data structure in RAM and sic a bunch of parallel threads to analyze or search it. It is hackable if you mash your data structure into a large byte binary, since large bins live on a shared heap, but it's a pain to deal with non-native representation for your data.
It's very obvious that Erlang is optimized for a particular usage model, and even when you're dealing with a number of functional parallel processes, it might still clash with what you're doing.
If you need a multi-gigabyte, read-only, in-memory data structure with support for ad-hoc querying and concurrent reads... you probably should just use a SQL database.
The content is quite interesting, but this paper could use some serious editing. There are typos throughout, and the tone is overly colloquial for an academic context.
The paper could also use an evaluation section - e.g. implementing a solution to a well known problem like the Dining Philosophers in both languages and comparing both the code and runtime characteristics.
I strongly disagree in regards to the colloquial aspect you mentioned. Academic papers have no reason to be pompous or high level and can benefit from increased visibility by presenting the findings in a more colloquial manner.
What's wrong with colloquial style? Perhaps the usual stuffy style of academic writing is a trapping to avoid, not something to imitate and perpetuate.
The report mentions Quasar (I'm its main author) and simply says, "instrumentation has many challenges that add complexity to the program instead of removing it." -- without mentioning why. I believe this is false. Quasar removes just as much complexity as Erlang does (Erlang's enforcement of immutability is orthogonal; indeed, if you use Quasar with Clojure you get that, too), but it is true that the instrumentation is not entirely transparent -- yet. This doesn't add any complexity to the program (the code is exactly the same as it would be in Erlang), but it does add some difficulty to the compilation process, as all blocking methods must be annotated. This is an annoyance, but it will probably go away in Java 9, as we are working with Oracle to make a minor change to the JVM (no, unfortunately not building continuations into the JVM just yet) that will make the bytecode instrumentation process fully automatic and completely transparent.
Fibers implemented with bytecode instrumentation also have some (small) added overhead (which is why we'd like them to be built directly into the JVM), but this makes little difference in practice: HotSpot's compiler is so good that with any added real work, that overhead is becomes negligent, and the compilation quality means that overall performance exceeds anything that can be achieved by Erlang VMs.
Also, the report says: "the JVM has a single heap and sharing state between concurrent parties is done via locks that guarantee mutual exclusion to a specific memory area. This means that the burden of guaranteeing correct access to shared variables lies on the programmer, who must guard the critical sections by locks". This is grossly inaccurate. While it is true that the JVM has a shared heap, this means that it can allow programs to share mutable state among threads -- not that it necessarily does so. The JVM leaves the concurrency model up to the language implemented on top of it (just as the hardware and OS support a shared heap, but various languages may choose not to expose that as a visible abstraction to program code). E.g. Clojure only allows shared mutable state if it enforces transactional modifications. Erlang also allows this kind of shared state via ETS; the difference is that ETS must be programmed in C, whereas on the JVM you can write the shared data structure in a JVM language. This also means that on the JVM, objects stored in such a concurrent data structures are handled by the GC, whereas in Erlang (IIRC) ETS cause some issues with GC (EDIT: in fact, ETS data is not garbage collected at all).
I believe that the JVM is a strict superset of any Erlang VM. In particular, HotSpot (the OpenJDK's JVM) is so well implemented, that the main difference -- even when running programs that behave just like Erlang program -- is a huge boost in performance, and never needing to use C to achieve either good performance or some behavior that is unsupported by Erlang semantics.
Maybe I should make the argument as to why ETS is not garbage collected. It is a pragmatic solution to an often occurring problem in software.
You have a lot of data.
You rarely change that data.
You still have to walk over it when you garbage collect.
ETS allows you to store Erlang terms into a tuple space outside the heap of any process. This means you avoid garbage collecting, and you can have 120 gigabyte of RSS, but only have to collect 400 megabytes of those. If you look at how many "mmap" implementations there are for GC'ed languages, and if you have ever reached for one, you know what I'm talking about.
Take the fastest webserver written for Java and for Erlang. Now run static requests around 2048 bytes, 10k connections, 3 req/s on each connection for 5 minutes. Measure the 99.9th percentile latency.
Erlang wins by a large margin because the JVM has to garbage collect and block everyone while doing so. This is not desirable in a soft-realtime system.
I'd definitely not order one as the strict superset of the other.
Regarding the JVM as a strict superset, there are a few features I'm not sure fit that model.
Isolated garbage collection. Limiting GC to a single process/thread. It's my understanding that this is only possible with individual heaps, prohibiting shared memory. I see this as a polarizing tradeoff (with pros and cons). I don't think the JVM does this, and therefore isn't a superset.
Preemptive scheduling and soft real time. It's my understanding that Quasar bridges this gap by looking for natural points in execution to insert a pause/continue (oversimplified I'm sure). What are the guarantees? Erlang provides fairly strong guarantees about fair scheduling, making it very suitable for soft real-time systems. Would Quasar, for instance, pause a tight for loop if execution was running long? Or does it only pause on blocking operations like IO?
> I believe that the JVM is a strict superset of any Erlang VM.
I don't get how JVM is a strict superset of Erlang VM when it doesn't have pre-emption.
If BEAM set have preemptive scheduler as an element and JVM, IIRC, does not have such feature, then JVM is not a super set let alone a strict super set.
whereas in Erlang (IIRC) ETS cause some issues with GC
There isn't any at all for ETS:
Note that there is no automatic garbage collection for
tables. Even if there are no references to a table from
any process, it will not automatically be destroyed
unless the owner process terminates. It can be destroyed
explicitly by using delete/1. The default owner is the
process that created the table. Table ownership can be
transferred at process termination by using the heir
option or explicitly by calling give_away/3.
Of course, you'll seldom be using ETS directly, but rather through Mnesia.
Hi! I'm the author of the paper referenced by this post and let me start off by saying that you're right in that the paper didn't do justice to Quasar. I kindly apologies for this. I actually did want to revise that section before submitting, but as usual, the deadline came first and that section remained in my opinion one of the most "hand-wavy" ones.
Mostly the comment about "adding complexity", comes from my own biased experience of working with bytecode instrumentation. I work on the JRebel team @ZeroTurnaround and as you can imagine, we have to do quite a bit of instrumentation to get this nice reloading behaviour. Though as Murphy's law states, if something can go wrong it will and if something goes wrong after instrumentation then debugging it will not be a pleasant task. Which of course doesn't mean that it can't work nicely eventually, proven by our large number of happy customers.
Quasar's own documentation states that "If you forget to mark a method as suspendable ... you will encounter some strange errors. These will usually take the form of non-sensical ClassCastExceptions, NullPointerExceptions, or SuspendExecution being thrown". I think forgetting something is a very human thing to do and when you've got a large codebase then debugging such exceptions is what I meant by "adding complexity". But again this was only a speculation.
Regarding the other comment about shared mutable state, then of course it isn't necessarily required and I did write in the summary that "Java and the JVM provide enough tools to retrofit any concurrency model out there, but retrofitting anything won’t be the same as taking it into the initial design", which I do think still holds and I believe is one of the reasons why using libraries like Quasar won't be a trouble free experience, at least not until it's somewhat built into the JVM.
Though I won't even try to claim to know the ultimate truth and I'm always grateful to have someone correct me when I'm wrong. I appreciate your efforts in trying to make the JVM a better/more versatile platform with Quasar. I think that any such bold undertaking will only benefit the ecosystem in the long run.
It reads like it was written by an undergraduate for independent study credit, or as a lit review for a future non-doctoral thesis. Certainly no result here, just a survey.
[+] [-] jfaucett|10 years ago|reply
It also reminded me how much I wish there was an actual specification for BEAM, finding out the details of the how the bytecodes work is an arduous task compared to the JVM where everything is explicitly stated. IMHO both VMs are excellent in their own right, the HotSpot JIT is incredible, but I still can't deny that I find the beam process model on concurrency more elegant than the JVM one, though in practice I've only toyed in erlang so I have no real-world grounds of comparison there. Does anyone by chance?
[+] [-] jlouis|10 years ago|reply
[+] [-] vezzy-fnord|10 years ago|reply
Otherwise, a decent high-level overview.
[+] [-] white-flame|10 years ago|reply
One major thing that turned me off of the language for our particular project was that there was no way to have a large read-only data structure in RAM and sic a bunch of parallel threads to analyze or search it. It is hackable if you mash your data structure into a large byte binary, since large bins live on a shared heap, but it's a pain to deal with non-native representation for your data.
It's very obvious that Erlang is optimized for a particular usage model, and even when you're dealing with a number of functional parallel processes, it might still clash with what you're doing.
[+] [-] vtuulos|10 years ago|reply
http://discodb.readthedocs.org/en/latest/
https://github.com/discoproject/discodb
[+] [-] sargun|10 years ago|reply
[+] [-] rudiger|10 years ago|reply
[+] [-] hendzen|10 years ago|reply
The paper could also use an evaluation section - e.g. implementing a solution to a well known problem like the Dining Philosophers in both languages and comparing both the code and runtime characteristics.
[+] [-] kkirsche|10 years ago|reply
[+] [-] mwcampbell|10 years ago|reply
[+] [-] pron|10 years ago|reply
Fibers implemented with bytecode instrumentation also have some (small) added overhead (which is why we'd like them to be built directly into the JVM), but this makes little difference in practice: HotSpot's compiler is so good that with any added real work, that overhead is becomes negligent, and the compilation quality means that overall performance exceeds anything that can be achieved by Erlang VMs.
Also, the report says: "the JVM has a single heap and sharing state between concurrent parties is done via locks that guarantee mutual exclusion to a specific memory area. This means that the burden of guaranteeing correct access to shared variables lies on the programmer, who must guard the critical sections by locks". This is grossly inaccurate. While it is true that the JVM has a shared heap, this means that it can allow programs to share mutable state among threads -- not that it necessarily does so. The JVM leaves the concurrency model up to the language implemented on top of it (just as the hardware and OS support a shared heap, but various languages may choose not to expose that as a visible abstraction to program code). E.g. Clojure only allows shared mutable state if it enforces transactional modifications. Erlang also allows this kind of shared state via ETS; the difference is that ETS must be programmed in C, whereas on the JVM you can write the shared data structure in a JVM language. This also means that on the JVM, objects stored in such a concurrent data structures are handled by the GC, whereas in Erlang (IIRC) ETS cause some issues with GC (EDIT: in fact, ETS data is not garbage collected at all).
I believe that the JVM is a strict superset of any Erlang VM. In particular, HotSpot (the OpenJDK's JVM) is so well implemented, that the main difference -- even when running programs that behave just like Erlang program -- is a huge boost in performance, and never needing to use C to achieve either good performance or some behavior that is unsupported by Erlang semantics.
[+] [-] jlouis|10 years ago|reply
You have a lot of data.
You rarely change that data.
You still have to walk over it when you garbage collect.
ETS allows you to store Erlang terms into a tuple space outside the heap of any process. This means you avoid garbage collecting, and you can have 120 gigabyte of RSS, but only have to collect 400 megabytes of those. If you look at how many "mmap" implementations there are for GC'ed languages, and if you have ever reached for one, you know what I'm talking about.
[+] [-] jlouis|10 years ago|reply
Erlang wins by a large margin because the JVM has to garbage collect and block everyone while doing so. This is not desirable in a soft-realtime system.
I'd definitely not order one as the strict superset of the other.
[+] [-] phamilton|10 years ago|reply
Isolated garbage collection. Limiting GC to a single process/thread. It's my understanding that this is only possible with individual heaps, prohibiting shared memory. I see this as a polarizing tradeoff (with pros and cons). I don't think the JVM does this, and therefore isn't a superset.
Preemptive scheduling and soft real time. It's my understanding that Quasar bridges this gap by looking for natural points in execution to insert a pause/continue (oversimplified I'm sure). What are the guarantees? Erlang provides fairly strong guarantees about fair scheduling, making it very suitable for soft real-time systems. Would Quasar, for instance, pause a tight for loop if execution was running long? Or does it only pause on blocking operations like IO?
[+] [-] digitalzombie|10 years ago|reply
I don't get how JVM is a strict superset of Erlang VM when it doesn't have pre-emption.
If BEAM set have preemptive scheduler as an element and JVM, IIRC, does not have such feature, then JVM is not a super set let alone a strict super set.
[+] [-] vezzy-fnord|10 years ago|reply
There isn't any at all for ETS:
Of course, you'll seldom be using ETS directly, but rather through Mnesia.From: http://www.erlang.org/doc/man/ets.html
[+] [-] poolik|10 years ago|reply
Mostly the comment about "adding complexity", comes from my own biased experience of working with bytecode instrumentation. I work on the JRebel team @ZeroTurnaround and as you can imagine, we have to do quite a bit of instrumentation to get this nice reloading behaviour. Though as Murphy's law states, if something can go wrong it will and if something goes wrong after instrumentation then debugging it will not be a pleasant task. Which of course doesn't mean that it can't work nicely eventually, proven by our large number of happy customers.
Quasar's own documentation states that "If you forget to mark a method as suspendable ... you will encounter some strange errors. These will usually take the form of non-sensical ClassCastExceptions, NullPointerExceptions, or SuspendExecution being thrown". I think forgetting something is a very human thing to do and when you've got a large codebase then debugging such exceptions is what I meant by "adding complexity". But again this was only a speculation.
Regarding the other comment about shared mutable state, then of course it isn't necessarily required and I did write in the summary that "Java and the JVM provide enough tools to retrofit any concurrency model out there, but retrofitting anything won’t be the same as taking it into the initial design", which I do think still holds and I believe is one of the reasons why using libraries like Quasar won't be a trouble free experience, at least not until it's somewhat built into the JVM.
Though I won't even try to claim to know the ultimate truth and I'm always grateful to have someone correct me when I'm wrong. I appreciate your efforts in trying to make the JVM a better/more versatile platform with Quasar. I think that any such bold undertaking will only benefit the ecosystem in the long run.
[+] [-] ScootyPuff2000|10 years ago|reply
[+] [-] leothekim|10 years ago|reply