ORCA (and Pony language) solved this while allowing selective mutability and zero-copy message passing improving on Erlang HiPE/BEAM by tying objects to a tiny heap with individual actors (cooperative async threads). There is no global locking in Pony except in limited circumstances.
Zulu C4 is an improvement. Schism and Metronome are less pausey but slower overall.
https://www.azul.com/products/components/azul-zulu-prime-bui...
https://dl.acm.org/doi/10.1145/1809028.1806615
https://researcher.ibm.com/researcher/view_group_subpage.php...
This is why I don't understand the WASM GC proposal, which I understand to be an attempt to make a GC that works for all languages. Can you really write a GC that performantly supports both Java and Go given the different tradeoffs/approaches each makes with respect to memory management, layout semantics, etc?
[1]: https://users.cecs.anu.edu.au/~steveb/pubs/papers/g1-vee-202...
That is the cool thing about having multiple implementations.
I heard not so good things about Herb Schildt's book.
1. The Java Programming Language book:
The K&R of Java
https://www.amazon.com/Java-Programming-Language-4th/dp/0321...
2. Zantorc's videos: https://www.youtube.com/@Zantorc/
He really gets into the nitty gritty. You can listen to this while commuting, etc; Just finish 1 video per 3 days, say. It adds up quickly.
Otherwise, start with G1 and get your Xmx value in the ballpark. VisualVm can help you determine if you're thrashing. Are you GCing like 10+ times per second? Keep an eye on it. If you start hitting giant pause times and 50+ collections a second, you've got problems :) Increase Xmx. (and no, please don't set Xms = Xmx).
If you have issues past that, it’s not the garbage collector that needs help; the next step is to audit your code base. Bad code makes any Garage Collector in any language to misbehave.
For instance, are you `select *`ing from a table then using the Java streams api to filter rows back from a database? That will cause GC issues :) fix that first.
So now if you've got to this point and you still need to optimize, what we've done is just run through the different collectors under load. One of our JVMs is a message broker (ActiveMQ 5.16.x) and we push a couple thousand messages per second through it. We found that Shenandoah actually improved latency for our particular use case, which was more important that throughput and outright performance.
Oh, and if your application and usecase is _extremely_ sensitive to latency, forget everything I wrote and contact Azul systems about their Prime collector. They're pretty awesome folks.
[0] https://docs.oracle.com/en/java/javase/18/gctuning/introduct...
throughput: parallel or G1
balance between latency, footprint and throughput: G1
latency more important than throughput or footprint: ZGC or shenandoah
missiles and HFT: Epsilon
My java/kotlin app needs to keep a big table fully in memory. (~10 million records). And it is reloaded about 3 times a day. In C, I would just malloc the whole table in one chunk. Perhaps there is a specialized GC for this usage ?
For best performance you can decompose your structure to primitive fields (int, float, char, etc) and create array for every field. So you have, say, 10 arrays with million items each. Instead of creating one array which holds pointers to another 10 million objects on the heap. It gets tricky with strings (you need to flatten all strings into a giant char[] array and keep two arrays with index and length data, but doable.
Though 10 million of records might be OK for JVM. Measure your GC times.
I'd suggest to hide implementation details behind API, start with ArrayList<MyRecord> and refactor it later if needed.
Beware that you're gonna have to filter a lot! There's patch merging and very low detail implementation conversations. For example, you'd be pleased to know that G1 can now skip a guard in card-table clearing [4]. Don't ask me what is the card table and guards and why do you need to clear it, though.
One thing I'm looking for in GC advances is new hardware support for it in RISC-V J extension. There's gonna be memory tagging (helping security and memory management in GCs), and pointer masking (hardware support for what ZGC does under the hood)[5]. But we're probably a good 5 years away from seeing that in real life, if ever.
[1] https://mail.openjdk.org/pipermail/loom-dev/
[2] https://mail.openjdk.org/pipermail/hotspot-gc-dev/
[3] https://mail.openjdk.org/mailman/listinfo
[4] https://mail.openjdk.org/pipermail/hotspot-gc-dev/2023-March...
[5] https://github.com/riscv/riscv-j-extension/blob/master/point...
Besides the JVM resources linked by others, I found Richard Jones's "Garbage Collection Handbook" to be a decent introduction for background [1]. The Go team has written a bunch about their GC approach [2] - it is really interesting to see how it compares to the various options in the JVM and under which scenario you might prefer one or the other. And occasionally there are interesting articles on arxiv.
:-/
Java is such a storied and long-running and used-almost-everywhere language especially in Data Engineering (see all the Apache Data Eng projects like Calcite, Hudi, etc) but I just find it soooooo verbose and everything being a class and having to override things ugh .. it's all the things I hate about OOP in the forefront.
[1] https://openjdk.org/projects/amber/
Most of the time the complexity in my code has little to do with Java being verbose and more due to the business problem. There are areas to improve and Java's been making great strides recently. For example, in Java 21 we may finally have methods like getFirst() and getLast() for lists (via JEP 431) instead of the incredibly clunky list.get(list.size() - 1). Java also recently added multi-line Strings and templating is coming shortly. Streams and Optionals also reduce quite a bit of boilerplate, e.g. Optional's map and ifPresent methods are often elegant. Really I can't think of many other areas where Java gets in the way. Our team is incredibly productive with modern Java.
I think most developers actually write overly verbose code regardless of the language. And it seems little to do with years experience. This youtube channel covers most of the basics:
https://www.youtube.com/@CodeAesthetic
To me I just follow these recommendations naturally but in most PRs I review there's often huge amounts of overly nested code, poorly named methods, etc.