Quality rant, thanks a lot.
The Oracle JRE is the standard one, but it is not open-source; its standard gratis license does not allow to run applications for commerce/non-privately.
Speed. I don't know how long the Oracle JRE takes to start; classically, JREs took ages start because they have to load lots of bloat. Once it runs, though, the Oracle JRE is fast; they invested lots of research into fast JIT. The managed code will run as fast as native code, maybe even faster depending on what exactly it does.
For the very few Java apps that I use, I've always used OpenJDK, but I haven't run anything performance-heavy. I should pay attention to OpenJDK's start times the next time I reboot the machine
, i.e., in a few weeks. >_>In my day job, there is a Java rewrite of the crusty C/C++ project underway. Both run semi-embedded: The software gets autostarted after Linux boots, and little else runs on that target machine. Allegedly, the Java application needs over a minutes more to start compared to the native application. Don't know if we can chalk 100 % of that up to the JVM, though, but probably for a sizeable chunk of the time, yes.
Java runs very slowly on my Mac, for some reason, and that is a bit disappointing, but not annoying.
Stuff on computers should run blazingly fast. Anything slow is a huge problem. Latency is a huge problem. People should not be conditioned to wait on slow software/hardware, or to consider slowness merely disappointing. Stuff must be blazing fast!
If programs are slow, I will forget what I want to do, I will start other things in the meantime, and will not use those programs in the best possible way. E.g., I will consider workarounds to avoid the slow features. The time-limiting factor should be my thinking, or my typing speed.
This Torvalds quote from the 2007 git talk is spot-on:
People seem to think that performance is about doing the same thing, just doing it faster, and that is not true. That is not what performance is all about.
If you can do something really fast, really well, people will start using it differently. One of the things I wanted to make sure is that merges go really really quickly because I want people to merge often and merge early, because as it turns out it becomes easier to merge. [if you merge often]
GUI on Java: The idea that it looks the same on each platform means that it looks awkward on each platform. I believe it's possible to have native widgets instead of the Einheitsbrei, but few designers pick the native widgets for their GUI application. The non-native Java GUIs feel slow, lots of latency, not snappy.
Memory management. One benefit of managed code (i.e., not native code) is that the JRE can force all allocations to go on its managed heap, have fine control during garbage collection (GC) and can implement fast GC algorithms, search://generational gc/.
For games, it's usually okay if they crash when out of memory. Thus, it's sad if the JVM is really so terrible at handling OS memory.
Rambling on memory management, side-tracking, not necessarily a discussion of merits of the Java ecosystem.
Compare the managed code with natively compiled D where we still have a GC, but now we have pointers into native memory: The GC will halt the program, then must scan the entire of the address space of the program, free unused memory, and then resume execution. We can't have the really smart algorithms, I believe this is because the GC isn't allowed to reallocate ad libitum, to keep the native pointers valid. Still, the worse GC isn't a dealbreaker at all in Lix, and I've seen at least one more D game dev say that you can force the GC to run 60 times per second with no problems on typical games.
You can avoid GC in D, but it's not as comfortable. In general, GC is a performant strategy anyway: You don't have to reference-count everything, that would introduce another indirection in your data structures, and you still don't have to manage manually. The closest manual strategy is arena allocation: You allocate a big chunk of memory in advance before play, serve small chunks of it as necessary, never free during play, and only at end of level, you free the entire arena in one single go.
Fine control during ouf-of-memory. It's not necessarily acceptable even for a game to just crash on out-of-memory. If one wants more control during out-of-memory, e.g., to save the game in some allocation-free way before crashing. In sandbox games or grinding games, this appears really important. But I'm not sure how easy that is with the Java memory model.
I'd want to pre-allocate an arena just for that, to still have this memory guaranteed even when the host machine runs out many hours later. These ideas are at the heart of the Zig programming language, where allocation is always explicit, and libraries are encouraged to accept an allocator from the caller instead of hard-wiring one on their own.
The side effect of this is that programs must always be very explicit about error handling. You can't have the nice functional pipelines
someRangeOfObjects.map.filter.fold...-- Simon