7 ms·
Other systems I'm aware of that are capable of similar feats (I know .NET's collector can, not sure about Hotspot's) use page poisoning. Basically the compiler/
by johncolanduoni 10y ago
Other systems I'm aware of that are capable of similar feats (I know .NET's collector can, not sure about Hotspot's) use page poisoning. Basically the compiler/JIT puts a bunch of extraneous memory accesses to a known address at key points where the GC can track what all variables and registers hold (called "safepoints"), in a fairly liberal pattern around the code. When the GC wants to stop all the threads in their tracks, it unmaps the page holding that address, causing segfaults in every thread it it hits one of the safepoints. The GC hooks the segfault handler, and simply waits for all threads to stop.
I'm not sure that's what Go does, but I'm not aware of a faster way on standard hardware.
- pcwalton 10y agoThat's basically what Go does; it folds the preemption points into the stack checks during function prologs.
- hinkley 10y agohopefully in back branches too, right?
- pcwalton 10y agoNot according to this bug. :( https://github.com/golang/go/issues/10958 https://github.com/golang/go/issues/10958
- menzoic 10y agoWhere did you learn that? (curious to learn more)
- ci5er 10y agoI haven't seen it written up, but it's discussed some here: - https://github.com/golang/go/issues/10958
- pgwhalen 10y agoHotspot does that as well. Really nifty stuff.
- geodel 10y agoHotspot worst case (non) guarantees are 100s of milli seconds not 100s of micro seconds.
- pcwalton 10y agoAgain, you're comparing the server G1 GC (tuned for throughput) to Go's GC (tuned toward extreme latency guarantees).
- inlined 10y agoIs this a bad thing? You can just increase the number of front-end servers and have high throughput in a service with reliable tail latency.
- heavenlyhash 10y agoThis. It's a lot easier to horizontally scale things with a lean towards consistently lower operational latency. You can keep raking in the benefits and cranking up throughput without a whole lot of thought. It's much more expensive and complex to take an erratic latency operation and bring it down by throwing on more resources. As far as I can tell, the normal design course is making sure all your major actions are either pure or idempotent allowing parallel (and redundant!) requests to be made... which is a large (worthy, but large) engineering effort, and then we're talking about scaling to 2x or more just so you can make that redundant-request thing your default behavior.
- jsiepkes 10y agoIn case of Java there is also a JVM implementation that does pauseless GC (zing): https://www.azul.com/products/zing/pgc/ https://www.azul.com/products/zing/pgc/ . For OpemJDK/Hotspot there will be a <100ms GC in Java 9: http://openjdk.java.net/jeps/189 http://openjdk.java.net/jeps/189
- geodel 10y agoJava 7 and above provide XX:MaxGCPauseMillis flag for GC conf From Mechanical Sympathy Blog [1] " G1 is target driven on latency –XX:MaxGCPauseMillis=<n>, default value = 200ms. The target will influence the amount of work done on each cycle on a best-efforts only basis. Setting targets in tens of milliseconds is mostly futile, and as of this writing targeting tens of milliseconds has not been a focus of G1. " So in Java world we are talking 100s of milli seconds of worst case which is 3 order of magnitude higher than Go. 1. http://mechanical-sympathy.blogspot.com/2013/07/java-garbage-collection-distilled.html http://mechanical-sympathy.blogspot.com/2013/07/java-garbage...
- pcwalton 10y agoWell, yeah. You're comparing the G1 (for server workloads) to Go's concurrent collector. There's a concurrent collector you can use in incremental mode for the JVM if you want to trade throughput for pause time, like Go does. The HotSpot designers have (correctly, IMO) observed that server use cases typically prefer throughput to latency. On a meta note, I wish people would focus on the actual algorithms instead of taking cited performance numbers out of context and comparing them head to head. The Go GC uses the same concurrent marking and sweeping techniques that CMS does. This change to avoid stop the world stack sweeps is something that no HotSpot collector does. But it's counterbalanced by the fact that Go's GC is not generational. Generational GCs change the balance significantly by dramatically improving throughput.
- sambe 10y agoIn my experience you are still getting single-to-double-digit millisecond pauses on average using CMS (even with some attention/tuning). Do you really think Hotspot can offer a GC where pauses longer than 100us are considered interesting enough to look into?
- pcwalton 10y agoSure, if they implement barriers for stack references like Go is. But that's a significant throughput hit.
- matthewwarren 10y agoInteresting enough .NET doesn't use the "memory access" trick, instead is uses either a direct poll against a variable, or for user code can sometimes just rudely abort the running thread (if it knows it's safe to do). See http://mattwarren.org/2016/08/08/GC-Pauses-and-Safe-Points/ http://mattwarren.org/2016/08/08/GC-Pauses-and-Safe-Points/ for all the gory details