Think this will obsolete go over the next few decades.
Think this will obsolete go over the next few decades.
I'd be surprised if Go adoption plummeted because of this, but who knows, I sure don't have a crystal ball.
I think it's all a moot point though, as it basically just demonstrates the next iteration of Paul Graham's Blub Paradox. With every iteration of new improvements for the JVM it reinforces the belief of many that the JVM is the best tool for every job (after all, it now just got cool feature y they just now learned about and can use and OMG Blub-er-Java is so cool, who needs anything else?!), and reinforces the belief of many others that the JVM is playing catchup with other languages (it only just -now- got feature y) and there are often better tools out there.
The path of least resistance in Scala leads to immutable collections.
In Go/Kotlin, one can atomically take from/send to exactly one channel with the `select` call.
Then I agree with "weirder" as well, in the case of Go channels. A send on a nil channel blocks forever. Why?
Channels exhibit the following properties:
* send to a nil channel blocks forever
* receive from a nil channel blocks forever
* send to a closed channel panics
* receive from a closed channel returns the zero value immediately
I have this bookmarked because I don't write Go enough to remember it by heart.The executor services referred to in the blog are for the order of execution of tasks on the virtual thread pool. For a "virtualThreadExecutor" service, every task will get a virtual thread and scheduling will happen internally.
You can still use a fixed thread pool with a custom task scheduler if you like, but probably not exactly what you are after.
Maybe a little disappointing for low level nuts and other languages like kotlin, but the right move IMO. Virtual threads alone will be a huge benefit to the ecosystem. The other stuff will help, but won't have near the same impact.
If anything, if Loom is great, then it will keep Go on its toes and hopefully Go will also evolved due to external pressure.
At which point would you say Java has improved enough to catch up with Kotlin (supposing Kotlin does not also keep improving)? As a long-term user of Kotlin, I would say I would not reach out for Kotlin anymore for new projects. The last remaining big thing Kotlin gives is non-nullability, but with simple tools, Java also has that already.
My point being, Kotlin vs Java isn't just about language features, it's about community, ecosystem, use cases etc.
(Fwiw, personally I prefer Kotlin because it's more expression oriented than Java.)
Imitation can only get you so far. Java is changing, and in many cases for the better, by absorbing features from other languages. However, I still think several other languages do a better job curating features to fit a niche.
That said, Loom appears to be a serious upgrade for JVM languages. Now, if startup could get an order of magnitude faster...
You can kinda do this with futures but I suspect it'll be wildly inefficient. I really hope Java get's something to fill this niche. We already have a menagerie of Queue, BlockingQueue, and TransferQueue implementations. What's a few more?
Kotlin coroutines have the bare minimum in the language, and implement the rest (e.g. channel, select, `go`/`launch`) in libraries. Could you explain what the dividends for Go are?
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutin...
https://openjdk.java.net/jeps/8277129
But frankly I'm afraid of how these changes affect garbage collection since more and more vthread stacks are going to be in the heap (I hope they are contemplating some form of deterministic stack destruction along with the above JEP).
People don't pick up Go over Java because of goroutines, Java is still and will forever be an "enterprise" language behind many layers of abstractions.
Writing a “hello world”-scoped microservice is a tiny niche.
Also have you proof that Go will die under large memory usage? It's FUD.
The Debian binary-tree test is designed to create a ton of allocations and stress the GC. Go comes in at 12.23 seconds with Java at 2.65 [0]
Discords famous article about moving a service off Go because of GC issues [1]
I think there is definitely enough evidence to suggest that Go’s GC does have performance issues and doesn’t give you the knobs to tune it.
[0] https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
[1] https://discord.com/blog/why-discord-is-switching-from-go-to...
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
As for Discord it was a specific use case, it does not means Go has specific GC issues overall. How Java would have compared against Rust? 100% sure it would have performed worse, but you can't say for sure that Java would have performed better, especially after a re-write, rewriting the Go Discord Go in Go could have fixed the issue, no one knows.
The JVM is probably heavily optimized for what a binary tree is doing, does not mean the JVM overall is better for all use cases.
And by “what a binary tree is doing” you mean like.. garbage collecting no longer used objects? Like, why is it hard to believe that the runtime on which perhaps the majority of serious, huge web services run (twitter, apple’s web services, but google as well are huge java shops), the likes of which handle 325,000 transactions per second (Alibaba) underwent a tremendous amount of engineering and in the GC category is definitely the queen?
Where you can get away with barely any allocations is a much smaller niche even for microservices. And Java’s GC is in an entirely other generation of GCs compared to Go’s.
- Garbage collectors have required far less tuning; with G1, Shenandoah, ZGC it's likely that your application will need little tuning on normal sized heaps.
- modules, jlink etc allow one to build a much smaller Java application by including only those parts of the JVM that one needs.
- Graal native images are real. These boast a far lower startup overhead and much lower steady state memory usage for simpler applications.
Probably my counterexample of choice is this: https://github.com/dainiusjocas/lucene-grep - it uses Lucene, one of the best search libraries (core of Elasticsearch, Solr, most websites), which is notoriously not simple code, to implement grep-like functionality. In simple cases, they demonstrate a 30ms whole process runtime with no more than 32MB of RAM used (which looks suspiciously like a default).
The JVM is fast becoming a bit like Postgres... one of those 'second best at everything' pieces of tech.
/usr/bin/time -l ./hello-world
Hello World!
0.00 real 0.00 user 0.00 sys
3231744 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
841 page reclaims
1 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
2 voluntary context switches
4 involuntary context switches
22395110 instructions retired
18507246 cycles elapsed
1294336 peak memory footprint
So "peak memory footprint" for hello world is 1.2 MB and it starts instantly.Now, not everyone can/will use AOT compilation. It's slow to compile and peak performance is lower unless you set up PGO, plus it may need a bit of work in cases where apps assume the ability to do things like generate code on the fly. But Go can't do runtime code generation easily at all, and if you are OK with those constraints, you get C-like results.