Live data from Hacker News

Z Garbage Collector: The Next Generation

inside.java

101–110 of 126 posts

Re: Z Garbage Collector: The Next Generation

#101
post #11

Earlier quoted context omitted.

I think it was a tongue in cheek reply, as it is indeed a no-code, no-pause, no-compute power GC that does eventually reclaim the garbage (at process exit).

Correct me if I am wrong but does it really GC at all if you receive an OutOfMemoryError?

It’s meant for short lived apps where you simply wouldn’t get OOM either way. I don’t know about an objective definition for what a GC is, one I quite like is “gives the illusion of infinite memory”, based on that it isn’t a GC.

But there are also conservative GCs, RCs, etc, that fail different definitions also (leaving behind circular dependencies, having false positives, in reverse order), like in case of many things in CS, there isn’t an objective definition.

Re: Z Garbage Collector: The Next Generation

#102
post #101

Earlier quoted context omitted.

Correct me if I am wrong but does it really GC at all if you receive an OutOfMemoryError?

It’s meant for short lived apps where you simply wouldn’t get OOM either way. I don’t know about an objective definition for what a GC is, one I quite like is “gives the illusion of infinite memory”, based on that it isn’t a GC. But there are also conservative GCs, RCs, etc, that fail different definitions also (leaving behind circular dependencies, having false positives, in reverse order), like in case of many thin…

Thank you for the explanation, I think I get it now!

Re: Z Garbage Collector: The Next Generation

#103
post #97

Earlier quoted context omitted.

Rust's lifetimes is a strict subset of the general case, but it covers a good majority of use-cases with affine types - which means trivial allocation and deallocation. The number of times I had to use lifetime specifiers or dynamic lifetimes (RefCell/Rc/Arc) is extremely low, so low that it is not even a blip on the profile. Also, unlike most GC languages, Rust favors stack allocation over heap allocation, which mak…

In my experience most applications do need an escape hatch from a strictly tree-like lifetime pattern, it really is limiting. Object layout is the primary reason for the performance differences between low-level languages and manages ones — Java uses a thread local allocation buffer, which is for all practical purposes just as hot as the stack. What is more expensive is arrays of references and such, but that will be…

> EDIT: What I’m trying to say is that there is very little overhead to creating short-lived objects in Java.

I've been working on high performance Java software (databases) for many years now and the overhead of creating short lived objects is bearable only because we're going so far trying not to create those objects, writing Java in a kinda C-style - no objects, just primitives as much as you can.

The total overhead is not just bumping up the pointer and zeroing memory but actually all what happens when the GC runs out of the slab. By allocating short lived objects youre making GC collect earlier and overall doing more work. Also the faster you allocate, the more objects survive the collection and more objects must be copied. That process is very expensive and also very complex.

Re: Z Garbage Collector: The Next Generation

#104
post #98

Earlier quoted context omitted.

The statement was that ZGC (or any JVM GC for that matter) is better than Rust’s GC, which is just naive ref counting. This is true - if we were to create a program that allocates the same amount in both implementations, Java would win by a huge margin.

Have you ever tested it by yourself? I tested and no, it didn't win by a huge margin. Malloc+free was only a tad slower than the default Java GC new (stop the world, parallel) but the default GC is much faster than G1 and ZGC so I would not be surprised if malloc could beat those modern ones at allocation rate benchmark.

Do you have a public benchmark for that? It’s quite hard to write a benchmark that actually measures what we are interested in. Not doubting you, I would be interested only.

Re: Z Garbage Collector: The Next Generation

#105
post #93

Earlier quoted context omitted.

Even then updating the counter is still more work than tracing collectors do, which is nothing almost all the time. > refcounting doesn't do pauses at all At the cost of throughput. BTW, I'm not comparing Java to Rust, just ZGC to Rust's GC. I am well aware that it is not used for most objects.

But reference counting is just a tiny subcomponent of Rust's GC. The majority of Rust's automatic memory management is based on affine types and static code analysis, not refcounting. You're just picking subcomponents to make Java solution look better, but what matters for developers is the whole picture. And BTW, I wouldn't be so sure about throughput either. ZGC is capable of allocation rates of the order of only ~…

I thought I made it clear in my last comment that I'm not claiming that Java's memory management is somehow "better" than Rust's. I was merely pointing out that even Rust has a GC, and it's not a good one, but it might certainly be good enough for Rust's needs as it doesn't depend on it. Overall, obviously Rust and Java choose very different tradeoffs in their memory management strategy.

> ZGC is capable of allocation rates of the order of only ~5 GB/s

That was the non-generational ZGC. Indeed, ZGC's max throughput was well below that of ParallelGC and G1. One of the main goals of generational ZGC is to increase the throughput, and as you can see in the video, they got a 4x increase in throughput.

Re: Z Garbage Collector: The Next Generation

#106
post #56

Earlier quoted context omitted.

It does not. Maintaining the counter requires more work than tracing GCs do, and you don't know in advance when the last reference is dropped. True, you get more promptness in deallocation (not the same as predictability), which reduces the footprint but comes at the expense of compaction, the lack of which in most refcounting GCs also adds unpredictability. In contrast, in the common case, allocation with a compacti…

Ah, it's that topic again. The whole point "but refcounting requires more maintenance per object than GC" is totally moot when there are only 0.01% of objects being refcounted (in Rust or C++) vs 100% objects traced by GC in Java.

I never claimed otherwise. Java's and Rust's overall memory management strategies are far too different to compare. I was talking specifically about refcounting vs tracing.

Re: Z Garbage Collector: The Next Generation

#107
post #104

Earlier quoted context omitted.

Have you ever tested it by yourself? I tested and no, it didn't win by a huge margin. Malloc+free was only a tad slower than the default Java GC new (stop the world, parallel) but the default GC is much faster than G1 and ZGC so I would not be surprised if malloc could beat those modern ones at allocation rate benchmark.

Do you have a public benchmark for that? It’s quite hard to write a benchmark that actually measures what we are interested in. Not doubting you, I would be interested only.

This has been on my list of next blog posts for so long. But unfortunately no, not yet.

Re: Z Garbage Collector: The Next Generation

#108
post #89
post #86

Earlier quoted context omitted.

Not sure what startup time matters for running a persistent service is, and it's obviously tied to hardware. You can get applications up and running in less than second or so (we were using Micronaut to resolve dependencies at compile time). If you use GraalVM you can compile to native code and now we're talking a few tens of milliseconds to get an application up and running (or execute and exit).

That was always the story back then, too — the assumption that no one writes anything other than services with long uptimes. No CLI tools, no lambdas, no quick-launching GUIs. Sounds like that bias hasn't really changed over the years?

You pay for what you use. If you bring in a litany of libraries to connect to some endpoint in every conceivable IPC mechanism then sure, it will take some time (but let’s not forget that it would also take considerable time with native machine code). But besides very very frequently run CLI tools like ls, the problem is entirely overblown. Come on, quick-launching GUIs? I hardly even remember that being a thing.

Re: Z Garbage Collector: The Next Generation

#110

Earlier quoted context omitted.

As far as I know, ZGC uses a lot memory than G1, and for as long that's the situation, it's unlikely to replace G1 as a default configuration. Another understanding I have is that ZGC is best used for large workloads, compared to G1 which is more generalized and doesn't perform as well with larger workloads. But, I'm no JVM experts and might have understood it incorrectly. Happy to be corrected!

Yes, on small heaps you are still forced to use a 64bit pointer instead of a 32bit pointer, which means that your per-object overhead is higher, this means that on "normal" heap sizes, That said, for a lot of use cases, this is still a reasonable trade-off to make, but it probably won't be promoted to "standard" until it's better in all use cases.

Wouldn't UseCompressedOops flag alleviate the issue for smaller heaps?
Post reply on HN