1. It compiles statically down to machine code; there's no JIT or bytecode interpretation execution path.
2. It offers straightforward control over the memory layout of your data structures (it doesn't offer straightforward control over the lifecycle of your memory, which is the next step towards the metal that Rust takes).
The advantage is that casual Go code is generally going to be more efficient both in execution and memory usage than a casual program in a higher-level language. You can make Java do almost anything; the important thing is what languages make easy, not what they make possible.
Memory layout is a valid point though. C# with its value types gives you a lot more control than Java does, but is still often grouped with Java, and I think rightly so. Go's pointers go quite a bit further, but then on the other hand, it also has high-level data structures like map as language primitives, which makes it less close to the metal as far as I'm concerned.
I'd personally group all GC'd languages in roughly the same class here, but I think it's reasonable to disagree or make finer distinctions.
I'm also not saying JIT vs. AOT is an irrelevant distinction in practice -- like everyone else, I like my programs to start fast. But in the end, you have machine code in RAM either way; the level of abstraction is, all else being equal, the same.
The precise details of how that machine code gets there change nothing about how the program is written. The emphasis people put on those details aren't always warranted. I don't think they matter at all for typical backend code, which is one of Go's main niches.
Edit: The earlier version of this response was maybe unnecessarily pointed, I expanded and toned it down a bit.
Java is planned to gain an equivalent of this ability through primitive classes (JEP 401). As as i know, we expect to get a preview of this feature in Java 19, which should be released in September this year.
Now what is the advantage again? The Java can compile to JVM bytecode and be better performing than golang, all while having superior introspection and monitoring and debugging abilities. It seems to be a win-win. Only some ideological "closer to the metal" philosophy doesn't apply, so what?
If startup times are truly an issue, look at Quarkus[1] and Micronaut[2], and a lot of other frameworks that use GraalVM to compile to native binaries.
It's kind of true... but with so many caveats it's almost a lie.
* it compiles so slowly even basic applications can take 10 minutes to compile. What the hell are they doing all that time?!? Go can compile to multiple OSs architectures on the same machine and it takes a couple of seconds even for large code bases!!
* you can't use most of the Java ecosystem as reflection is endemic... good luck manually declaring everywhere reflection will be used.
* the loss of the JIT hurts peak Java performance a lot. Java runs as fast as Go *once the JVM is warmed up*! Native-image peak performance tends to be some way behind.
Not saying GraalVM native-image is useless, it can be used if you have the energy and knowledge to get past the issues... but as someone who konws Go as well as Java, if I am going to the trouble of going native, I'd just use Go without a doubt.
ExcelsiorJET, J/Rockit, Websphere Real Time, PTC or Aicas aren't GraalVM.
Also if you don't want to lose JIT, while having the advantage of AOT compilation, JIT caches are a thing, nowadays available for free on OpenJDK, OpenJ9 and Android (even though it isn't proper Java).
Go and Java make different tradeoffs. If you're unreasonably effective in Java and its tradeoffs work for you, that's completely fine. If you have good tools that make Java more like Go when you need Go-like characteristics, that's cool too.
Go has pretty good introspection with pprof it's enough, you don't need something heavy like JFR. For debugging delv is ok, not on part with C++/ Java but it's fine, you can even do remote debugging now.
The thing is with Java and to some extend C#, yes they have different runtimes, VM, AOT / JIT etc .. different thing to compile to native binary: none of them are really mature atm and moreover it's even more complexity for the programmer, now he has to choose which runtime or compiler he's going to use, it's crazyness. Same story with the GC Java offers, too much choice, too much burden on the programmer. For app A you're going to use this GC + runtime, app B is going to be different, it really mess up the dev / ops process.
Real world programs disagree. And for any large program, the JVM is a superior optimizer than golang's compiler.
> As for the tooling that Java has those it's because the language and runtime or so complicated with many layer of abstraction that you need those.
I heavily disagree. I deployed services both in golang and Java/JVM languages, and simplicity of the language or runtime has nothing to do with the JVM having superior observability and monitoring.
> you don't need something heavy like JFR
I wonder why my employer is spending millions of dollars on dev salaries to build something not even remotely comparable to the JFR for their golang programs then.
Secondly, the JFR is extremely light weight, and gives you < 1% overhead at runtime. Show me another ecosystem that gives you this out of the box.
> Same story with the GC Java offers, too much choice, too much burden on the programmer.
It doesn't really. The newer GCs have very few knobs to turn. Compare to when you hit GC issues in golang, the solution is to rewrite code in nonidiomatic ways as we saw with Discord. The first approach is superior.
Sure, Java has much more need of dev tooling than Go. But the available dev tooling on Java being enough better than the Go tooling to make the language + tooling have a better DX can still (if that is one's experience) be a valid advantage, for anyone not working in an artificially constrained environment where they are forced to code with Notepad and no tooling.
Additionally, JIT caches are now part of OpenJDK, OpenJ9 and ART.
I never understood Go. I was sold as the C killer and failed, now it's basically an alternative to Erlang/Elixir, but suddenly people started running around and saying "Noooo, it was never meant to be a systems programming language like C!!!"
Secondly, Java can be tuned, but its default mode of operation is to take up the most amount of memory it can in order to give you higher performance (thoughput and latency). `-Xmx` is a thing.
Finally, now with GraalVM going mainstream, and frameworks like Quarkus[1] and Micronaut[2], you are able to compile Java programs to native binaries and also have lower memory usage if that's truly a restriction.
Some people really don't want to tune VMs. No one is saying Java doesn't have a place too. Jeez, dude.
I like Java (used to _love_ it about 26 years ago... been a decade since I've written any) but Go is actually a breath of fresh air for typical cross-platform systems programs.
Ironically Sun invented Java because lots of people bitched against TCL's non GPL license. Ironically, TCL/TK since 8.4 ran much snappier and faster than any Java turd even in 2004. Even simple Java 2D indie games looked laggish against AMSN, which was a "biggie" TCL/TK MSN clone back in he day.
But I think Java comes from something rather older, designed for interactive television, way back before anyone outside CERN had really seen a web browser. In that way the JavaStation is philosophically much closer to the roots of Java than the Java applet.
Also GraalVM is not 3rd party but also not OpenJDK. It is Oracle product and where many perf related features are only in enterprise version. Also it does not support most of JFR JVM monitoring.
I am perfectly fine people/companies paying for performance. But it is not like Native image is trivially applied to any existing Java project. Either one has to use limited frameworks that you keep listing or spend endless hours in generating native json files to cover reflection cases.
Source: https://www.karimarttila.fi/languages/2018/11/13/go-good-pro...
This proves my thoughts that these claims are not valid.
This is also misleading. You are implying that GraalVM isn't relatively new and that Java native compilation isn't rare. I've yet to see anyone deploy service or CLI tools that are natively compiled in Java. That statement is about as true as saying you can compile Python natively. Just because its possible doesn't mean the language is actually suited for it.
Nice joke. Go software runs much snappier and faster than any Java GUI or CLI tool.
Java CLI tools compiled with GraalVM start up just as fast.
Python is actually compiled. When you run a file, it firstly compiles the cod into a bytecode, which is saved in ‘.pyc’ files. These are afterwards interpreted by the interpreter.
Also, decoupling of the runtime from the language is huge, and lets us have nice languages like Clojure and Scala on the JVM.