Analyze 5 features that make the Go language efficient (5/5): Goroutine Stack Management

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Translate the original link reprint/reprint please indicate the source

English original link published in 2014/06/07

Stack Management for Goroutine

In the previous article, we discussed the Goroutine reduced administrative overhead for hundreds of concurrently running threads. Here we are going to discuss another aspect of Goroutine, its stack management.

The following is a memory layout for a process. What we care about in this diagram is the location of heaps and stacks.

Typically, in the process's addressing space, the heap is at the bottom of the memory and is derived from the program's executable instruction store (text). The stack is located at the top of the virtual address space and is derived downward.

If the heap and stack are covered by each other, the result is catastrophic. The operating system typically sets an area of non-writable memory between the heap and the stack. If the heap and stack are derived together, the program exits. This area of memory is called the Guard page. It limits the size of the stack of the process. This limit is usually in the magnitude of several m.

We talked about threads as shared addressing spaces. But for each thread, it has to have its own stack.

Because it is difficult to predict how much stack space a thread needs, much of the memory space is reserved for the thread's stack and the protection page to expect the reserved stack space to be large enough to protect the page from being touched. The disadvantage of this is that as the number of threads in the program increases, the available addressing space is correspondingly reduced.

We have already discussed that the run environment of Go will dispatch a large number of goroutine on a few threads. So how are these goroutine stacks managed?

The go language does not use the Protect page mechanism. The go compiler inserts a piece of code at each function call to check if there is enough stack space to run the called function. If there is not enough space, the run environment of GO will allocate more stack space. Because of this checking mechanism, the initial stack of a goroutine can be very small. So the go programmer can use Goroutine as a relatively inexpensive resource.

Shows how the stack is managed in Go 1.2.

When G calls H, there is not enough stack space for H to run, and then the Go runtime allocates a new stack memory block from the heap to let H run. The newly allocated memory block is freed back to the heap before H returns to G. This kind of management stack method generally works very well. But for some code, especially recursive calls, it causes the program to constantly allocate and free up new memory space. For example, in a program, function g calls many times the H function in a loop. A new memory space is allocated for each invocation. This is the thermal splitting problem (hot split problem).

To solve this problem, Go 1.3 uses a new stack management approach.

If the goroutine stack is too small, it will allocate a new larger stack instead of allocating and interpreting additional memory space. The contents of the old stack are copied to the new stack, and the goroutine will continue to execute on the new stack. After the first call to the H function, there will be enough stack space so that future stack size checks will not be problematic. This solves the problem of thermal fragmentation.

variables, inline, escape analysis, Goroutines, and stack chunking/replication management are the 5 features that I'm going to discuss today. Of course the go language is efficient not only because of these 5 features. It's like there are all sorts of reasons to learn the go language, and these reasons are never 3.

Each of these features is effective, and they are interdependent. For example, without a derivative stack, it would not be effective for the runtime to reuse multiple goroutine on the thread. Inline also avoids the check overhead of stack size when merging multiple small functions into large functions. The escape analysis uses stacks instead of heaps to store local variables, which also reduces the pressure on the garbage collection mechanism. Escape analysis also improves caching performance (cache locality). There is no derivative stack, and the escape analysis can cause great pressure on the stack.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.