Live data from Hacker News

Z Garbage Collector: The Next Generation

inside.java

91–100 of 126 posts

Re: Z Garbage Collector: The Next Generation

#91

Earlier quoted context omitted.

The answer is 6 years old if we count the last modification time.

And the last modification was only wording, with the same 13 years old content. [0] Always check what changed in SO posts, because this practice is very common. [0] https://stackoverflow.com/posts/2682962/revisions

TIL, thank you!

Re: Z Garbage Collector: The Next Generation

#92
post #35
post #28

Earlier quoted context omitted.

If we can know exactly where a particular object’s lifetime ends, then indeed we can write more efficient programs than possible with a GC, but that in the general case is not something we can determine at compile time (Rust’s lifetimes are a strict subset of the general case). Anything more dynamic will require some “ad hoc, informally-specified, bug-ridden, slow implementation of a GC”.

Rust also relies on a GC for the more dynamic lifetimes in Rust programs (reference counting), it just doesn't call it a GC, and while Rust's GC has a lower footprint than tracing GCs, it has worse performance and it suffers from cycle problems. I wouldn't call it "bug ridden" (perhaps "limited" is a better term), but it is slow. Some think that reference counting gives better performance predictability than a tracin…

> Rust's GC (...) has worse performance [than tracing GC]

That's an unsubstantiated claim.

While reference counting may be slower than tracing in the general case, Rust's reference counting is not the same thing as general reference counting in languages like e.g. Swift or Python. There are two reasons:

- The good majority (99%+) of objects in Rust don't need to be managed by reference counting at all.

- Rust relies heavily on move semantics to avoid updating the ref-counts, so the good majority of refcounted objects have very few (sometimes just 1) refcount updates.

> reference counting gives better performance predictability than a tracing GC, but that is no longer true, certainly compared to the generational ZGC presented here.

Where does ZGC claim nanosecond latency? But even if it did, it would be still worse, because refcounting doesn't do pauses at all. Pausing applies to pausing all application threads. Spending X nanoseconds freeing memory by one thread does not count as a pause, because the system can still make progress.

Re: Z Garbage Collector: The Next Generation

#93
post #35

Earlier quoted context omitted.

Rust also relies on a GC for the more dynamic lifetimes in Rust programs (reference counting), it just doesn't call it a GC, and while Rust's GC has a lower footprint than tracing GCs, it has worse performance and it suffers from cycle problems. I wouldn't call it "bug ridden" (perhaps "limited" is a better term), but it is slow. Some think that reference counting gives better performance predictability than a tracin…

> Rust's GC (...) has worse performance [than tracing GC] That's an unsubstantiated claim. While reference counting may be slower than tracing in the general case, Rust's reference counting is not the same thing as general reference counting in languages like e.g. Swift or Python. There are two reasons: - The good majority (99%+) of objects in Rust don't need to be managed by reference counting at all. - Rust relies…

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.

Re: Z Garbage Collector: The Next Generation

#94
post #56
post #50

Earlier quoted context omitted.

It does give better performance predictability! Decrementing a refcount may either be a no-op or expensive but crucially the op can happen only during that particular call, nowhere else.

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.

Re: Z Garbage Collector: The Next Generation

#95
post #37
post #31

Earlier quoted context omitted.

Tim sort, used in python, V8, Android, and Swift, was invented in this millennium.

And there are yet newer and faster sorting algorithms being implemented.

Notably quadsort which if I’m remembering my etymology correctly has pdqsort, fluxsort, and glidesort as descendents

Re: Z Garbage Collector: The Next Generation

#96
post #93

Earlier quoted context omitted.

> Rust's GC (...) has worse performance [than tracing GC] That's an unsubstantiated claim. While reference counting may be slower than tracing in the general case, Rust's reference counting is not the same thing as general reference counting in languages like e.g. Swift or Python. There are two reasons: - The good majority (99%+) of objects in Rust don't need to be managed by reference counting at all. - Rust relies…

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 ~5 GB/s, which is way below the theoretical memory bandwidth. I bet jemalloc can do much better.

Re: Z Garbage Collector: The Next Generation

#97
post #28

Earlier quoted context omitted.

If we can know exactly where a particular object’s lifetime ends, then indeed we can write more efficient programs than possible with a GC, but that in the general case is not something we can determine at compile time (Rust’s lifetimes are a strict subset of the general case). Anything more dynamic will require some “ad hoc, informally-specified, bug-ridden, slow implementation of a GC”.

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 solved by value types once, hopefully.

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

Re: Z Garbage Collector: The Next Generation

#98
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 ~…

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.

Re: Z Garbage Collector: The Next Generation

#99
post #11

Earlier quoted context omitted.

Epsilon doesn't GC at all?

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?

Re: Z Garbage Collector: The Next Generation

#100
post #98

Earlier quoted context omitted.

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 ~…

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.
Post reply on HN