This makes Java better in some fundamental ways, but I'm failing to see what advantages it has over C# outside of the JVM being supported just about everywhere (which is admittedly a pretty big deal in itself).
Honest question, what is the GC situation like on .NET? (Granted, it's easier to reduce the need for it with widely available and integrated inline types.)
The default GC has had some major performance improvements in .NET Core/5+. If you look up the performance improvement blog posts on MS dev blogs that come out shortly before each new .NET release you can see some of the details. Definitely not the same wealth of alternative GCs like there are available for Java, but it performa significantly better than it did in. NET 4.x.
Also there have been tons of overall improvements to decrease total heap allocations, see Span<T> for one of the biggest ones.
I think the often missed context of "C# vs Java" discussion is that the comparison itself is flawed. In the public perception they are bundled together but this couldn't be more wrong.
Due to decisions in how their respective platforms/runtimes are implemented, and subsequent decisions in the languages themselves, the current day situation is that Java is the more "focused" one, excelling in "business programming" kind of codebases - OpenJDK, on average, tolerates extremely heavy codebases better. C# on the other hand has historically been more of a "swiss army knife" that cowered wider range of paradigms (including FP: higher order functions, pattern matching, LINQ) but ended up leaning quite heavily towards lower-level, or more expressive, constructs: structs, generic monomorphization (with structs), async/await and tasks, different flavours of AOT, fast FFI.
It also made key choices that did lend themselves to nicer performance foundation: all method calls are direct unless explicitly marked as virtual/abstract, cheaper virtual and interface dispatch, (already mentioned) true generics, monomorphized for structs and unsafe subset of syntax that allowed to overcome compiler weakness quite a bit or make more calls for fast path in C++ where-as the breakout point in slower JNI was higher.
As a technology, C#/.NET was in many ways better, but as a product it was worse - it was close source, source available at best. OpenJDK also caught up and outpaced .NET Framework's JIT with HotSpot, massively improved tiered compilation capabilities and escape analysis, and GC implementations that Java ecosystem offered ended up being superior at the time.
Mind you, performance was still miles ahead of the likes of Python, Ruby and Node.js, but it was quite bad for a compiled language that sometimes looked like strange, if nicer, C++.
This, however, has completely changed when what today is called .NET was open-sourced. There were multiple events occurring in the ecosystem at the time (WinRT not doing as well, .NET Native UWP runtime, etc.), but the crux is - .NET Core 1, 1.1, 2, 2.1 up until 3.1 saw a huge amount of msft internal performance work (both .NET and e.g. Midori project) adopted in the open source .NET Core.
All areas saw improvement: GC, JIT codegen quality, new performance primitives (Span<T>, hardware intrinsics and co.), standard library and surrounding frameworks (ASP.NET Core, EF Core). I remember to this day seeing how latency of a particular request dropped from 2s to about 350ms with identical code after migrating a service from .NET Framework 4.6.2 to .NET Core 3.1. The improvements were massive.
In total, .NET saw significant perf. improvements in one area or another for every subsequent release, for 8 versions straight. As a result, it managed to close the gap with OpenJDK on allocation and abstraction heavy enterprise code, remaining just slightly worse, and started performing really well in other areas that do not exist in Java or only as incubator features (structs, Vector API which is nowhere near close).
By becoming well-behaved FOSS citizen .NET did away with its troublesome past, and the way I tend to describe C# today to people unfamiliar with it is it's a strange secret higher-level Rust with OOP features, GC and low-level escape hatch to push performance everyone is looking for but does not realize it's right next to them. For your question on "is GC an issue?" it rarely is, and you will find applications written in C# of today, if they have at least an ounce of engineer's care, to have an order of magnitude lower allocation traffic, and much smaller memory footprint.
Not sure if there is any relevant reason for this to be posted at this particular point in time. The most recent early-access build is from 2022: https://jdk.java.net/valhalla/
Edit: regarding replies about the recent update date -- that update date is tied to the linked Jira issue (https://bugs.openjdk.org/browse/JDK-8251554) and the only activity four days ago was adding links to some related issues. There were some updates to the description two months ago but the History view makes it difficult to determine what those are without manually copy-and-pasting the old revisions into some sort of diff tool
There's been a recent update to the proposed syntax & semantics, as indicated by the date on the JEP.
When I noticed the "preview feature" wording I went and tried running it with --enable-preview on a mainline OpenJDK build, but value records still didn't compile, and then I went back and saw that that wording has been on the JEP for some time.
There are also more up-to-date Valhalla builds available at builds.shipilev.net, but I'm not sure if there's some specific reason they haven't updated the EA page in years or if it's just not a priority.
> All Java developers would benefit if == ignored object identity and focused on the "essence" of the object
And yet, doing so is explicitly a non-goal of this work, is that because it needs a migration plan nobody can stomach? Before trying Rust I would have doubted that this just doing the Right Thing was important, but now I would co-sign that in a moment. I bet I've avoided a dozen bugs per year by having the == operator do what I meant not something that was easier to implement.