16 ms·
Go 1.4+ Garbage Collection Plan and Roadmap
- sudhirj 12y agoWhen there's talk of making sure the GC doesn't take up more than 10ms out of every 50ms, this is only when the GC is actually happening and not during regular running, right?
- judk 12y agoI think it means that GC will never run for a total of more than 10ms during any 50ms span. It doesn't mean GC would take 20% of total program runtime, except in worst cases. it means that GC will run often and concurrently enough that it won't "stop the world" too long.
- bearbin 12y agoYes, the 10ms out of 50ms blocked, plus at maximum 25% of the CPU time otherwise is only when the GC is running.
- kator 12y agoSTW has to die. I love that the goal is 10ms but in some environments the world has passed you by in 10ms and with STW you've timed out every single connection. I want badly to fall in love with Go, I've enjoyed using it for some of my projects but I've seen serious challenges with more then four cores at very low latency (talking 9ms network RTT) and high QPS.. I cheated in one application and pinned the go process to each cpu and lied to Go and told it there was only one CPU but then you loose all the cool features of channels etc.. That helped some but a Nginx/LuaJIT implementation of the same solution still crushed it on the same box, identical workload. It would be nice if we have to have STW to have it configurable, in some environments swapping memory for latency is fine and should be configurable. The way Zing handles GC for Java acceleration is quite brilliant, not sure how much of that is open technology, but it would be cool to see the Go team reviewing what was learned in the process of maturing Java for low-latency high qps systems.
- f2f 12y ago> lied to Go and told it there was only one CPU but then you loose all the cool features of channels etc.. channels work just fine in a single-cpu context. concurrency is not parallelism.
- dinkumthinkum 12y agoThat struck me as odd. I questioned the entire poster's results based on that statement.
- Jare 12y agoI took it to mean he launched several copies of the process, each copy pinned to one (and only one) core.
- kator 12y agoCorrect it was the only way to get Go to scale to a reasonable response rate for this application and it thus meant my CPU loading was not even since it was based on the randomness of socket connections that persisted on one cpu or another.
- coldtea 12y agoHe's not talking about merely being able to use channels in one core setup. This misunderstanding made me question your whole comment.
- scott_s 12y agoIt sounds like he wanted parallelism for performance.
- georgemcbay 12y agochannels work fine in a single-cpu context, but in the setup OP described you won't be able to use them to have the various processes talk to each other. At least not without using one of the various netchan-alikes or rolling your own channel<->ipc solution, neither of which is likely to result in an elegant solution (note how the original netchan was abandoned by the Go team).
- SEJeff 12y ago10 milliseconds is far too long for STP for anything in the financial industry. I can see it as also not being great for robotics or several other latency critical industries. It is a shame too. I love writing go
- schmichael 12y agoYou mention two industries with extremely demanding performance profiles (financial industry and robotics). I don't know if I'd trust any 5 year old platform in those contexts. There are lots of other contexts where the performance profile outlined in this document are sufficient. If you love writing Go, then I'd suggest staying out of the financial industry and robotics.
- jblow 12y agoAnd video games. And avionics/aerospace. And self-driving cars. And medical equipment. etc, etc. You can list lots of fields for which this is unacceptable, and they are a lot of the really interesting fields.
- ecuzzillo 12y agoNot sure about self-driving cars. I work in robotics, and there are a few modules that need to hit hard real-time deadlines. You wouldn't use GC languages for those, but there are a LOT of other parts that don't, and you can get a BIG win by writing those in a more concise language.
- SEJeff 12y agoGo was written by google for high throughput and concurrent infrastructure. The "web scale" problem is basically the polar opposite of the finance problem. That doesn't mean golang can't (eventually) be used in both, it just needs a bit of work before it gets there. As far as gc bits, the Azul Systems pauseless gc is certainly as state of the art as it gets. Too bad it is for java
- thrownaway2424 12y ago
- Thaxll 12y agoIs that possible to make a realtime gameserver with the actual GC?
- masklinn 12y agoDepends what you mean by "realtime". Pauses of 10ms is still 60% of a frame budget potentially every 3 frames. You're probably not simulating the game at 60fps, but it's worth about 2000 miles of network delay[0]. All in all, depends whether you're serving for a turn-by-turn roguelike, an RTS or an FPS. Won't be an issue for the first one, may not be for the second one, the latter though... [0] http://www.ibiblio.org/harris/500milemail.html http://www.ibiblio.org/harris/500milemail.html
- marvy 12y agoI smile every time I read that story. I'm up-voting for the link alone. (But yeah, it really sounds like they didn't have games in mind when they designed Go.)
- gillianseed 12y agoWell 'games' is a quite wide concept, there's been a ton of games released through XNA which used a 'stop the world' garbage collector until late in it's existence IIRC. So there's no reason why your typical indie style game would not be written in Go, but of course if you want to write AAA style 'push the boundaries of realtime graphics and physics', Go or any other garbage collected language is not a very likely candidate.
- marvy 12y agoNow that you mention it, I guess you're right. Even XNA would be bad if you're pushing the limits of the machine.
- ashleyw 12y agoI tried, but stopping the world hurts. Reusing stacks helps, but you're fighting the language from the very beginning. It wouldn't be a wise choice for even soft real-time IMO, you may as well just use Python or Ruby if you don't care about stopping the world..
- BinaryIdiot 12y agoI'm absolutely in love with C++'s RAII scheme but it seems almost no languages use it and, instead, go with a complex garbage collecting scheme that requires pausing. I want to like GO but a language that targets native development but still uses garbage collection just seems like an odd pairing to me. Maybe it's just me especially since I rarely get an opportunity to do native development.
- masklinn 12y ago> I'm absolutely in love with C++'s RAII scheme but it seems almost no languages use it RAII is but one resource-management strategy, and one intrinsically linked to C++'s memory model. But if that's what you're looking for, Rust uses the same: http://doc.rust-lang.org/std/ops/trait.Drop.html http://doc.rust-lang.org/std/ops/trait.Drop.html And in the absence of cycles, refcounted implementations have similar properties (although of course that assumption will break with alternate non-refcounted implementations if refcounting is not part of the language semantics). > I want to like GO but a language that targets native development but still uses garbage collection just seems like an odd pairing to me. Not that rare. OCaml is native and GC'd, so is D, or most lisps with native compilers. Hell, Boehm's GC exists.
- Cyther606 12y agoWith Nimrod, you can manage your own memory, or use the GC (Boehm iirc) http://nimrod-lang.org/manual.html#reference-and-pointer-types http://nimrod-lang.org/manual.html#reference-and-pointer-typ...
- dom96 12y agoIndeed, and Nimrod's own GC is actually soft real-time (http://build.nimrod-lang.org/docs/gc.html http://build.nimrod-lang.org/docs/gc.html) with hard real-time already in the works.
- dilap 12y agoObjC, with automatic-reference-counting (and now Swift, I assume, though I haven't looked into it) is close to garbage collection, but has deterministic destruction. The price you pay is you have to manually avoid cycles by annotating some references as weak. It's a very nice scheme, actually.
- davidtgoldblatt 12y agoFor those interested in additional technical details of high-performance garbage collection, the book cited (The Garbage Collection Handbook: The Art of Automatic Memory Management) is a fantastic reference. It's one of the best-written technical books I own, and distills much of the modern literature. If you need to do GC performance tuning or reason about memory management issues in the JVM, having this book around will be very useful.
- bcantrill 12y agoMy apologies for going off topic for a second, but is it well-known that Amazon seems to use Uber-esque surge pricing?! I (like apparently a lot of people) went to Amazon to buy the book cited as soon as I saw it (and it looks like a great book!). There were eight copies left in stock, and I bought it for $62.69.[1] When I went back to Amazon a few minutes later (following someone else's link), there was only one copy left in stock, and it was listed for $98.60.[2] With my apologies again for being off-topic, is this a known phenomenon? Anyway, thanks for seconding their recommendation of the book; I'm looking forward to reading it -- and glad I saved the 35 clams! [1] https://www.evernote.com/shard/s249/sh/53d7b93a-d737-41c4-8e2d-be8a48d88407/a6cc6a65f6890b77759ec1c9aef90a35 https://www.evernote.com/shard/s249/sh/53d7b93a-d737-41c4-8e... [2] https://www.evernote.com/shard/s249/sh/a1c55244-d64e-40cc-a6b0-b3941533a0e2/da97f45d87bdb50b47c80fb5cc02e16a https://www.evernote.com/shard/s249/sh/a1c55244-d64e-40cc-a6...
- deleted 12y ago[deleted]
- hiddencost 12y agoThose are two different books you've linked to...
- Malus 12y agoGarbage Collection: Algorithms for Automatic Dynamic Memory Management is the original book, whereas The Garbage Collection Handbook: The Art of Automatic Memory Management is the new and updated version. I have the original, but it would be nice to know everything the new book adds.
- dualogy 12y ago"Quantitatively this means that for adequately provisioned machines limiting GC latency to less than 10 milliseconds (10ms), with mutator (Go application code) availability of more than 40 ms out of every 50 ms" --- once they get there, they should try to make those targets customizable, with default values being 10ms/50ms. That'd be marvellous.
- ChikkaChiChi 12y agoGo is a language built on concurrency. Today's computers are usually allocated a lot of memory resources. Garbage collection is required but even a hybrid STW only reduces latency but doesn't eliminate it. Nor is there seemingly any foreseeable way of allowing developers to issue a GC request in a timely fashion. What if, prior to enacting GC, Go concurrently shifted from it's current memory allocation to an exact clone, cleaned up, then shifted back? Or maybe it cleans as it's cloning, enabling a shift to a newer, cleaner allocation? Sure, there would be latency during the switch, but it would be considerably less than stopping everything and waiting for GC to finish.
- howeyc 12y agoplease forgive my ignorance, but aren't you basically describing a "mark and sweep"[1]? [1] https://en.wikipedia.org/wiki/Mark_and_sweep#Moving_vs._non-moving https://en.wikipedia.org/wiki/Mark_and_sweep#Moving_vs._non-...
- aidenn0 12y agoI think that's closer to Cheney's algorithm (which is one of the easier ones to make bounded-latency actually).
- ChikkaChiChi 12y agoI'm new to these concepts, so please forgive me for coming up with something that already exists. I guess then the question becomes why would the roadmap avoid such an implementation?
- hedgehog 12y agoC4 is a well known pauseless GC, the paper is good and digging through the citations will get you pretty caught up on the theory and practice: http://www.azulsystems.com/sites/default/files/images/c4_paper_acm.pdf http://www.azulsystems.com/sites/default/files/images/c4_pap...
- jaekwon 12y agoCurious, how "real time" can a large application get in Go by judiciously working with pre-allocated structs and slices? Perhaps if the underlying system libraries don't require much garbage collection, then you can avoid stopping the world for too long.
- hedgehog 12y agoThat lets you make GC infrequent but the amount of heap will determine the pause time when the GC comes calling. If you have a large number of live objects with pointers in them then pauses are unavoidable with the current Go GC, it sounds like if all goes according to plan things will be a lot better in 1.5 though.
- twotwotwo 12y agoMore than many think. :) You can recycle objects to reduce GC frequency, reduce the number of pointer-containing objects to speed up the mark phase, batch or avoid allocations to speed the sweep phase. The sheer brawn of modern chips helps esp. given multicore GC; just sweating hotspots (e.g., big buffers) can do a lot; worst case, sometimes apps can be decomposed well into more processes each with their own smaller heaps. When GC comes up here (and not only on Go things), a lot of comments pop up that are like "welp, [tool] is no use for me if GC is involved," sometimes with a horror story or worst-case scenario. Sometimes I'm sure that's entirely rational and comes down to the type of app they work on (I don't wanna rewrite Unreal Engine in Go), but sometimes I wonder if whoever's saying it just doesn't know much about GC in practice.
- chetanahuja 12y agoSeems like the 10ms pause thing provokes a much sharper reaction (at least among this crowd) than this little nugget: "Hardware provisioning should allow for in-memory heap sizes twice as large as reachable memory." So I know "memory is cheap"(TM) but surely a 100% physical RAM overhead for your memory management scheme is worth at least a small amount of hand-wringing. No?
- acqq 12y agoIt is normal, not even a too big demand, as soon as you accept that the system depends on the GC. They are just being honest, even slightly optimistic. The current state of art is, you should suspect anybody who claims to you that GC systems don't need significantly more RAM. See for an example: http://sealedabstract.com/wp-content/uploads/2013/05/Screen-Shot-2013-05-14-at-10.15.29-PM.png http://sealedabstract.com/wp-content/uploads/2013/05/Screen-... (quoted in http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/ http://sealedabstract.com/rants/why-mobile-web-apps-are-slow...) According to the graph, most GCs start being really slow even with 3 times more memory than needed with the manual management.
- rbehrends 12y agoThat is misleading (and that article is really bad in other ways, too, but that's a different story). First of all, the "most GCs" are the non-generational GCs. That's well known. The amount of tracing work that a non-generational allocator has to do per collection is proportional to the size of the live set. Thus, collecting less frequently (by increasing the heap size before another collection has to occur) makes GC faster, using time roughly inversely proportional to how much bigger you make the heap. Generational collection can greatly mitigate tracing of the live set for when you have many short-lived objects that never leave the nursery. Second, the benchmark compares the allocation/collection work of various garbage collectors vs. an oracular memory manager using malloc()/free(). Not only do alternative solutions that don't use automatic memory management not necessarily match this performance (naive reference counting tends to be even slower, pool allocation also can have considerable memory overhead, etc.): more importantly, it's an overhead that applies only to the allocation/collection/deallocation work. For example, if your mutator uses 90% of the CPU with an oracular memory manager, then a 100% GC overhead means 10% total application overhead.
- eloff 12y agoPeople use the JVM in soft realtime / financial applications, and the trick is to reduce allocations, especially of objects that are long-lived enough to make it to gen 2. Go is better suited than Java for those kinds of applications, because it's easier to avoid allocations (Java doesn't have stack allocations, but Go does.) Also hard upper limits on GC time are very helpful for those cases where allocations can't be reduced any further. The standard library additionally has a Pool type that allows for reducing pressure on the GC through object reuse.
- munificent 12y ago> (Java doesn't have stack allocations, but Go does.) Go also lets you have fields in place in structs, like C and C++. In Java, all fields (except primitives) are references.
- seanmcdirmid 12y agoC# has had structs since V1 I think.
- bad_user 12y agoValue Types are coming in the next version of Java. Yes, it is great to be able to allocate on the stack, but then Java has better garbage collectors, including a completely pauseless one available commercially. Even in this announcement the new GC mentioned for Go is non generational. I have a feeling that even Java's good old CMS is better. Java also does escape analisys. All in all, once value classes are in, it is going to be awesome.
- _ak 12y agoWe use Go for a soft realtime application (RTB), and it works well enough. We essentially have two performance issues, one being the particular database we use (which is not directly related to Go itself), the other one being GC pressure. Before Go 1.3, too many allocations were _very_ noticeable with GC pauses sometimes being close to 100ms (which is a problem when your maximum RTT is 100ms), but Go 1.3 improved things enormously. I'm confident things will get even better with Go 1.4.
- smegel 12y agoAs a side issue, are there any plans to switch to gcc as thr main compiler? It can do everything that 6c can do from what I understand, and produces much faster code due to gcc well tuned optimizer.
- dsymonds 12y agogccgo sometimes produces faster code than gc, but not always. So no, there's no plans to replace gc with gccgo.
- twotwotwo 12y agoNope; gccgo is a separate project. Its good code generation is totally cool for particular purposes, but the Go project has its own priorities that they're going to implement in their own toolchain.
- jblow 12y agoAvailability of 40ms out of every 50ms... how many 9s is that? Oh wait. "Go, the language with zero nines of availability."
- kyrra 12y agoFrom my understanding, this only happens when the GC is run. Currently (Go1.3) the GC runs every 5 minutes or unless you manually invoke it. Currently the GC will stop the world and do the entire cleanup at once. From my understanding of this, the GC will do the cleanup in small 10ms bursts, so you won't have a 200ms pause every 5 minutes.
- andrewchambers 12y agoWhat you are saying is false. Even erlang will have some pause times, that has nothing to do with availability. And as mentioned, this is only when GC pauses happen.
- rurban 12y agoBe fast and use Cheney (copying, double memory) or be slow with Mark&Sweep and only the current memory usage. Nothing new here. Catching up old GCs via concurrent GC states is fine and tandy, but it is still just catching up, and it requires GC state. Cheney not. And a typical Cheney GC is 3-10ms not 10-50ms.