3 ms·
>In a properly tuned system with sufficient CPU capacity there should never be any full GC pauses with G1. So you use a language without value types that makes
by fauigerzigerk 11y ago
>In a properly tuned system with sufficient CPU capacity there should never be any full GC pauses with G1.
So you use a language without value types that makes you pay for two or three times more memory than comparable languages, and then you spend your time re-tuning the GC every time your allocation or usage patterns change. Then you hope to never trigger a full GC that could stall the VM for many seconds (or in extreme cases that I have seen even minutes). That makes very little sense to me.
I cannot speak to the performance of the current Go GC for 100G heap sizes. I never tried it and I haven't read anything about it. It's not my language of choice for that sort of task either.
- NateDad 11y ago100GB heap size in Go? How about 15ms pauses with zero tuning? https://pbs.twimg.com/media/CWoAGeUW4AAy0-9.png:large https://pbs.twimg.com/media/CWoAGeUW4AAy0-9.png:large
- sievebrain 11y agoThey aren't comparable at all. Go doesn't collect incrementally and doesn't compact. So good luck collecting garbage fast enough to keep up with a heap-heavy app (which if you have a 100GB heap, your app probably is). In other words, the issue is not pause time, it's also throughput. And Go users do tune their GC: https://github.com/golang/go/issues/14161 https://github.com/golang/go/issues/14161
- NateDad 11y agoBut Go programs use way less memory than Java applications... so the java application that uses 100GB might only use 40GB (or less) in Go. And there are tweaks you can make to hot code in Go to not generate garbage at all (pooling etc).
- sievebrain 11y agoJava's higher memory usage is not only related to value types, for example, in Java 8 strings always use 16 bit characters. That is fixed in Java 9. It resulted in both memory savings and speed improvements. There are other sources of overhead too, but again - you seem to think Go has some magic solution to these problems. Since the new GC, Go is often using a heap much larger (such as twice the size) of actual live data. That's a big hit right there. And yes, you have to tune the Go GC: https://github.com/golang/go/issues/14161 https://github.com/golang/go/issues/14161 Even when Java gets value types, it won't magically slash memory usage in half. Pointer overheads are not that large.
- fauigerzigerk 11y agoValue types are the main culprit behind Java's insane memory consumption. I found out through weeks of testing and benchmarking. I mostly benchmarked a small subset of our own applications and data structures. We use a lot of strings, so I never even started to use Java's String class, only byte[]. I tried all sorts of things like representing a sorted map as two large arrays to avoid the extra Entry objects. I implemented a special purpose b-tree like data structure. I must have tried every Map implementation out there (there are many!). I stored multiple small strings in one large byte[]. The point is, in order to reduce Java's memory consumption, you must reduce the number of objects and object references. Nothing else matters much. It leads to horribly complex code and it is extremely unproductive. The most ironic thing about it is that you can't use Java's generics for any of it, because they don't work with primitives. I also spent way too much time testing all sorts of off-heap solutions. At the end of the day, it's just not worth it. Using Go or C# (or maybe Swift if it gets a little faster) for small to medium sized heaps and C++ or Rust for the humungous sizes is a lot less work than making the JVM do something it clearly wasn't built to do.
- sievebrain 11y agoI admire your dedication to optimisation! But I think your conclusion is not quite right. I said above that pointer overhead is only one source of Java memory consumption, and pointed to (hah) strings as another source. You replied and said no, it's all pointers, followed by "I never even started using strings". Do you see why that approach will lead to a tilted view of where the overheads are coming from? If your application is so memory sensitive that you can't use basic data structures like maps or strings then yes, you really need to be using C++ at that point. In theory, especially once value types are implemented, it would be possible for a Java app to have better memory usage than an equivalent C++ app, as bytecode is a lot more compact than compiled code and the JVM can do optimisations like deduplicate strings from the heap (already). Of course how much that helps depends a lot on the application in question. But the sources of gain and loss are quite complex.
- fauigerzigerk 11y ago