This is a creation in Article, where the information may have evolved or changed.
Since Go1.5 introduced a real concurrent GC, Go1.6 has been further optimized to allow go to control STW time within 20ms of the heap size of hundreds g:
And Java8 's G1 collector, the default parameter under 100G above the heap, will cause the second level of STW. Although it can be -XX:MaxGCPauseMillis
adjusted, it is at the expense of large throughput. Here's an analysis of why go can do a shorter stw than G1.
Take turns hang up the co-process
The JVM's CMS collector is roughly divided into 4 phases when it works:
- Initial tag
- Concurrency token
- Re-tagging
- Concurrent cleanup
Of these, 1, 3 is the need to STW stage, the CMS's pause is also triggered by these 2 stages. The CMS in Go1.5 is also divided into these stages, where 1 and 3 also require STW. So why does go have less time to pause? The reason is that the go CMS does not suspend all Goroutine in the 3rd phase, but instead suspends it in turn. As a result, the 3 phase will not cause the entire program to pause, thus not counting into the STW time.
Time to go to trigger GC
The GC trigger conditions for GO are also very different from those of the JVM's GC. The JVM is typically used by the heap to reach a threshold, or the new
GC occurs when an operation fails. The GO is the GC that fires when the newly created object size is equal to the object that survived the last GC since the last GC . In this way, the pressure per GC will not be as large as the JVM, STW time is certainly much shorter, but also at the expense of throughput.
Go to generate less memory waste than Java
The objects of Go (that is, struct types) can be allocated on the stack. Go will do a static escape analysis at compile time, and if an object is found to have not escaped the current scope, the object will be allocated on the stack instead of on the heap, reducing the GC pressure. In fact, the JVM also has escape analysis, but unlike go, Java can not do this work at compile time, the analysis is done at runtime, so that it will take up more CPU time, and the second is not possible to all the non-escaped objects are optimized to the stack.
So far, go is not running as efficiently as the local machine code, which is better than Java, and I don't think it's a fault of Go, but the JVM's performance has been very good with the help of JIT. Even so, go optimizes the space to be larger than the JVM. I believe that the performance of Go will continue to improve in the future, will eventually exceed the JVM.