What are some fundamental Feature/Architectural difference between the BEAM and JVM?
The BEAM VM is optimised to solve many of these challenges by providing fine-tuned features which work on top of a predictable concurrent programming model. Its secret sauce are light-weight processes which don't share memory, managed by schedulers which can manage millions of them across multiple cores.
Erlang compiler to BEAM (byte-code VM) is written in Erlang.
June 2020) Elixir is a functional, concurrent, general-purpose programming language that runs on the BEAM virtual machine which is also used to implement the Erlang programming language.
First of all, Beam is a register machine, not a stack machine. Like the WAM for Prolog, it uses "X-registers" which are normal registers (implemented as an array in C), and "Y-registers" which are names for slots in the local function activation record (the "call frame") on the stack. There are no stack manipulation instructions.
Second, there are instructions for quickly allocating a few more words of heap memory, for initializing tuples and other data structures on the heap, for selecting elements of tuples, etc. JVM is focused on objects, and has a 'new' operation that hides the details of memory allocation and basic initialization.
The BEAM has an instruction for decrementing the "reduction counter" for the process and deciding whether it is time to yield to let another process run. JVM on the other hand has synchronization instructions for threads.
One important difference is that BEAM has tail call instructions, which JVM lacks.
Finally, for both the BEAM and JVM, the instruction set used in object files are really only a transport format. The BEAM emulator rewrites the instructions from the file into an internal version with many optimized special-case instructions (that can change from one release to another). Alternatively, you can compile to native code. Most JVMs do the same thing.
Some other interesting points are:
Processes are BEAM citizens and are managed by the VM itself while the JVM delegates their management to the OS. This allows the BEAM to manage (create, delete, context switch, ...) very quickly and, thus, to be able to manage hundreds of thousands of processes versus few hundreds of java threads on a reasonable machine.
On BEAM, inter-process communications is based on message exchange which eliminates most if not all situations which may lead to a race condition. On Java, you need to synchronize threads which is difficult and bug prone.
One important point is that garbage collection is done on a per process basis in the BEAM while it's a global process in the JVM. The impact is that a GC on the JVM may freeze the whole VM for possibly some seconds while on the BEAM each process has to give some of it's execution operations (reductions) to the GC without impact on the other processes.
Recently, some new libraries like VertX (I don't really know Akka but I believe it's the case) for JVM languages began to implement similar process behaviours to attempt to solve issues 1. and 2. I believe the problem of the GC cannot be solved with simplicity with a library, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With