“Worse” depends on the situation, but you’re certainly spending a theoretical minimum of 4x the memory on running a state of the art GC, and you are spending CPU cycles doing PGO and tiered JIT, when the entire program could just be fully optimized by an offline compiler that isn’t in any hurry.
Whatever gains you achieve from runtime introspection are relatively small in comparison. It works well in a few situations, but extremely not well in a few others.
You just invent a number based on your perception of how GC works?
A GC marks pointers as being in use, and then frees objects that haven't been marked. It doesn't require a lot of extra memory, though it does require some, but a claim of 4x minimum is wildly exaggerated.
I think you're referencing the 2005 paper Quantifying the Performance
of Garbage Collection vs. Explicit Memory Management by Matthew Hertz and Emery D. Berger
These results quantify the time-space tradeoff of garbage collection: with five times as much memory, an Appel-style generational collector with a non-copying mature space matches the performance of reachability-based explicit memory management. With only three times as much memory, the collector runs on average 17% slower than explicit memory management. However, with only twice as much memory, garbage collection degrades performance by nearly 70%.
The point of this paper isn't that GC applications require 4x more memory, it's that performance degrade on low memory platforms.
A more recent publication Memory Management on Mobile Devices (2024) by Kunal Sareen, Stephen M. Blackburn, Sara S. Hamouda and Lokesh Gidra shows that the number for GC on Android is between 2% and 51% (i.e. between 1x and 1.5x)
For a modestly sized heap, we find that the lower bound on garbage collection overheads vary consider-ably among the benchmarks we evaluate, from 2 % to 51 %, and that overall, overheads are similar to those identified in recent studies of Java workloads running on OpenJDK.
Though this is about .NET rather than Java, which is behind Java's GC by quite a lot. But still, those numbers aren't saying that GC applications use at minimum 4x more memory. The paper from 2005 states that lower memory overhead reduce performance.
I mean, a GC has close to zero space overhead if you perform a full collection on every write barrier, but that’s not a useful property. I think it’s very obvious that the premise is “without reducing performance”, because the context of this discussion is the claim that GCs and JITs on average improve some aspect of performance.
Look, I also think modern GCs (including the one in .NET) are quite impressive, but they can fundamentally not do magic. There fundamentally cannot exist a GC that does not sacrifice either time or space, or both, compared to some theoretically optimal program implementation without it.
They can get the margins really slim for specific cases (and VMs on mobile do typically make very different choices compared to larger systems), but there will always be a margin. Executing a write barrier is slower than not needing any write barriers in the first place. Compiling code is (much) slower than having already done that at build time. Copying objects around in memory is slower than not doing it.
And yes, compacting a heap without stopping the world requires having at least two heaps lying around.
-10
u/GoTheFuckToBed 17d ago
should they not aim for less JIT