5 ms·
I'd say it makes Java's GC worse at nearly every job as that means the defaults probably aren't what you want but are probably what you are going to use.
by eikenberry 4y ago
I'd say it makes Java's GC worse at nearly every job as that means the defaults probably aren't what you want but are probably what you are going to use.
- truffdog 4y agoThe Java problem is that you wind up in a blame game where one team blames the code and the other blames the GC settings and you wind up doing a lot of fruitless flailing. No knobs really cuts down on that nonsense.
- vips7L 4y agoIn situations where you actually are allocating on the heap, Java’s default GC significantly out performs Go’s. Just look at the binary tree bench marks. https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/binarytrees.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
- coder543 4y agoEven that simplification is too much. Java uses a generational GC, so the fewer objects that survive the nursery, the less work it has to do. That benchmark does not mean Java's GC is faster when you're "actually allocating on the heap". It means Java's GC is faster when you're spewing garbage onto the heap as fast as possible. Since Go makes heavy use of stack allocation where possible, short-lived garbage usually doesn't end up on the heap, but this benchmark is designed to force that outcome. Go's garbage collector is optimized to minimize latency and STW, but this does come at the cost of decreased throughput. The opposite can be said of the majority of Java GC implementations, which trade latency and STW time for increased throughput.
- vips7L 4y ago> Java uses a generational GC. This depends on implementation. ZGC is not generational yet, but I don’t see how generational or not would invalidate a GC benchmark for the default implementation. > That benchmark does not mean Java's GC is faster when you're "actually allocating on the heap". It actually does at least in the discussion of _default gc implementations_. Just because the default (and only) implementation for Go sacrifices throughput (and relies on the compiler to stack allocate) doesn’t invalidate the benchmark. And honestly if I was in Vegas I’d still bet that ZGC (Java’s non-generational, latency sensitive GC) would beat Go’s implementation here.
- coder543 4y ago> This depends on implementation. ZGC is not generational yet, but I don’t see how generational or not would invalidate a GC benchmark for the default implementation. I never said the benchmark was invalidated, I said that you interpreted the meaning of the benchmark wrong. I like how your reply completely ignored what I said the benchmark meant. That benchmark has a very narrow focus, and generational makes a huge difference for that one benchmark. > And honestly if I was in Vegas I’d still bet that ZGC (Java’s non-generational, latency sensitive GC) would beat Go’s implementation here. I would love to see a holistic set of benchmarks comparing them. Even just that one very narrow benchmark you linked would be fun to see — if ZGC is so good, surely one of the implementations of the benchmark on the website is using ZGC? But I haven’t had time to dig through them. But, part of Go’s charm is that idiomatic code rarely puts tons of pressure on the GC anyways, and a GC can never be faster than stack allocation for a multitude of reasons… which is also why C# has value types.
- jdc 4y agoJava's value types will be ready soon enough: https://openjdk.org/projects/valhalla https://openjdk.org/projects/valhalla
- coder543 4y agoI hope it happens soon! But, if I understood correctly, that design both requires you to explicitly mark a type as a value type when you define it and it doesn’t support inheritance, so I’m skeptical that it will see any real adoption for a long time. Java hasn’t had decades to develop a culture around this feature the way that C# has, and neither are like Go where everything is value typed unless it is one of the built in pointer types, or you explicitly put the value behind a pointer. (The pointers themselves are values, of course, but I think few people are interested in that distinction here.) Go isn’t perfect by a long shot, I just don’t think adding the millionth keyword is going to be a silver bullet for Java’s predisposition towards GC pressure.
- 4y ago
- kaba0 4y ago> That benchmark does not mean Java's GC is faster when you're "actually allocating on the heap" The benchmark doesn’t show it, but it is nonetheless true. Java uses thread local allocation buffers, which is possible due to moving GC, and it is literally as fast as it gets (a single, non-atomic pointer bump)
- coder543 4y agoAgain, GCs just aren’t that simple. You seem to be taking a very literal interpretation of what was said, but that person was implying that Go is only fast when you’re avoiding the heap. They weren’t talking about the actual, literal speed of allocation. My interpretation of their comment is confirmed in their later reply to me, as far as I can tell. Java’s GC design requires more barriers which hinder performance throughout the lifetime of a heap allocation, not just at the time the value was allocated. Either way, Go also uses per-thread caches in its allocator to avoid contention between threads. I don’t believe it is a bump allocator, but this goes back to other tradeoffs being discussed. The number of barriers, the duration of STW, etc. I don’t understand why so many people in here feel the need to declare the superiority of Java GC. Java’s garbage collectors are better for Java, due to the way that Java allocates practically everything on the heap. That doesn’t mean they have zero performance tradeoffs and that they’re perfect. They do have tradeoffs, and not just in complexity of tuning.
- kaba0 4y agoAs I mentioned in another comment, Java’s modern GCs don’t have many knobs at all - they are apt for most tasks by default.