3 ms·
Go programs don't just use less memory, the language makes it possible to control memory allocations. With the JVM-based languages I'm familiar with, it is dif
by enneff 14y ago
Go programs don't just use less memory, the language makes it possible to control memory allocations.
With the JVM-based languages I'm familiar with, it is difficult to control the memory allocation characteristics of you program, and typically the further the language deviates from the JVM's model (eg, Clojure and Scala) the more garbage must be generated (usually in doing= things like runtime type reflection).
All these allocations put pressure on the garbage collector and, fortunately, the JVM provides a few sophisticated garbage collectors. But even so, I am aware of some high profile companies whose JVM-based servers spend upwards of 80% of their CPU time in the garbage collector. It's just crazy.
On the other hand, the Go language and - critically - its libraries were designed to give the programmer control over the allocation patterns of the program. This creates less work for the GC, and leads to leaner services with predictable performance characteristics.
Go has other advantages over the JVM as a platform, but this is the critical one IMO.
- Locke1689 14y agoI don't see anything special in Go for commanding the GC, can you point me to these APIs?
- enneff 14y agoIt's not about commanding the GC. It's about avoiding unnecessary allocations.
- Locke1689 14y agoOK, can you be specific how this is done? What is the technical reason here?
- enneff 14y agoFor instance, in Go everything is passed by value. If you want to pass a reference, you must pass a reference type (like a pointer). This means that you can pass around structs without having to put them on the heap. In JVM-land, nearly everything is passed by reference, and the data must go on the heap. Relatedly, in Go if you allocate an array of n values of type T, the size of that array in memory is n * sizeof(T), and the items are laid out sequentially in memory. There are no other bookkeeping data structures and no indirection. Here's a story about one project's struggle with data structures and Java: http://marc.info/?l=git&m=124111702609723 http://marc.info/?l=git&m=124111702609723 Relevant quote: JGit struggles with not having an efficient way to represent a SHA-1. C can just say "unsigned char[20]" and have it inline into the container's memory allocation. A byte[20] in Java will cost an *additional* 16 bytes of memory, and be slower to access because the bytes themselves are in a different area of memory from the container object. We try to work around it by converting from a byte[20] to 5 ints, but that costs us machine instructions. In Go, you would just write [20]byte. If you wanted a struct with a field of [20]byte you can do so, and all it costs is the 20 bytes.
- Locke1689 14y agoThe JVM does not support this, but the CLR does.
- zaphar 14y agoGo's memory model has similarities to C. For instance you can use the heap or the stack. Go figures out which one an allocation should live in by doing escape analysis. If it never leaves the function it goes on the stack. If it does it goes on the heap. GC ensures anything on the heap gets cleaned up. It's not an API.
- pcwalton 14y agoTo be fair, Java does escape analysis for this too. This isn't a difference between Java and Go.
- Locke1689 14y agoBoth the JVM and the CLR do this. This is not a Go technology. In fact, in certain cases the JVM can detect type information and remove the allocation entirely by hoisting integer fields and the like into registers.
- ericbb 14y agoIt's not about escape analysis. The programmer explicitly specifies when to use pointers. Whenever pointers are not used, the object is stored in-place (for example, on the stack, in the array or slice, or in the struct).
- pron 14y agoThe only reason you hear less "crazy" Go GC stories is because Go has never been tested as much as the JVM under different application requirements. And if high-profile companies have servers that spend 80% of the time in GC -- well, they must have really neglected their code. That's a result of poor software maintenance, and I doubt any language could help them.
- martinced 14y agoNo... It's because Java totally sucks when objects go from Eden to Survivor and then needs to be GC'ed or from Eden to Survivor to Tenured and then needs to be GC'ed. That's the very reason why some trading companies who still insist on using Java do use methods where as few objects as possible are ever created and went on to invent things like the LMAX disruptor "pattern" (more like an anti-pattern, where the goal is to be as close to the metal as possible, by allocating gigantic primitive arrays... Quite the contrary of your beloved GC dogma, where you think that creating objects as no impact and that slow GCs are necessarily the programmer's fault). I realize from your various post that you did really drink the Java cool-aid and that no matter what's going to be said you'll always come touting Java as the best language out there. I know Java well enough to criticize it. I also have the impression that Go is used inside Google on some impressive tasks so I wouldn't be to quick to dismiss it.
- pron 14y agoI'm not dismissing Go, and I'm not praising Java, and I've even admitted on this very thread that Go is better than Java, so there's really no need in trying to convince me of anything. All I'm saying is that Go isn't good enough -- if I really want fast development and expressivity, there are languages more expressive than Go (more so than Go is to Java), and if I really need top-notch performance, then Java is OK and comes with some absolutely useful advantages that Go doesn't offer. I see excellent use cases for Python, for Ruby, for Clojure, for Java and for C/C++. I just don't see compelling use cases for Go. I'm not dismissing it. It's really nice. I just think it's underwhelming. And, BTW, if you think Go has some magic GC secrets that will make all (or even some) of the JVM GC problems go away -- I believe you're mistaken.
- spullara 14y agoIf they are spending that kind of time in GC, they are doing something insane. They should send email to hotspot-gc-use and get it solved. http://mail.openjdk.java.net/pipermail/hotspot-gc-use/ http://mail.openjdk.java.net/pipermail/hotspot-gc-use/