Also, much better tooling around Erlang processes than goroutines.
Processes are meant to model the real world. I'd say the truth is closer to "Any time you would instantiate an object in Java, you spawn a process." That's not always going to be true, but more true than you might expect.
BEAM has a very efficient multi core fair scheduler. All 2M process share time on all available cores and are handled by a single scheduler. Because it's preemptive, starvation problems one might see on an event loop are avoided. A CPU intensive process can run alongside low latency IO processes and they are all fairly scheduled.
In the analogy, it's like having 2M web servers, but where only, say, 1000 of them are actually running. As a developer having independent web servers helps you to think about what should be done instead of how it's going to be done. After that, the fact that a server is actually running or it is stalled because it's reading from disk or it is waiting for available CPU is an implementation detail and something that monitoring will show you.
Each erlang process has its own (erlang) heap and stack, and there is no ability within the Erlang language to access memory by address, a process will only access its own memory, or special types of shared memory (such as the shared/large binary heap).
From the OS perspective, it's one process, with one memory space, and several threads.
A realistic Erlang example where you would have 2 Million processes is something like a chat server (1 process per connected user), either via a traditional tcp protocol or a websocket protocol for a browser. In another language, you would likely need to multiplex multiple users onto each thread, in Erlang each user gets their own process and the code ends up being quite straight forward.
You can do actor model concurrency on Java (and Scala) with the Akka framework (http://http://akka.io). It's a pretty mature one as well. I've been using it for a while now.
Erlang processes are very lightweight (only a few KB of memory) yet they have the property of OS processes of keeping their data isolated.
Think about it like an operating system. In most programming platforms today you are essentially programming in Windows 3.1 or DOS. So when the calculator process crashes, it could take down your game or your word processor because they all share their memory space. That is all cool, but it is cool for 1994, not for 2016.
When programming in Elixir/Erlang/LFE, is like moving up the ladder and using a real OS (preemptable execution, processes don't mess with each other's memory, and so on).