This is a creation in Article, where the information may have evolved or changed.
Go language 1.2 was released today, and one of the changes was that the default stack size increased from 4096 to 8K. Remember earlier that the code changes were mentioned, but also to remind you that each network connected to open a goroutine now consumes memory will double. When I didn't think about it, I felt like it was. And it's not going to go into why the change was made.
Until today to see the route to go 1.3, one of the major changes that will be made in the next release is that the design of the staging stack is no longer used. This is why I think we should take a good look at the go language of the segmented stack design.
The first question is: 4k or 8k?
The first go to the initial stack size of a goroutine of 4k, just an operating system memory page size, this is not a thoughtful design. The size of this value should have been based on the stack size consumed by most goroutine runtimes, but it is clear that this statistic was not initially done. Later found 4k this value is not enough, so increase to 8k.
In fact, this value is set to 4k and there is no direct profit, not 4097 will need to allocate two times, and 4k need to allocate this.
The reason is that there are two layers of abstraction: The next layer is the operating system paging mechanism, the discontinuous physical memory is mapped in 4k per page for continuous virtual memory, the above layer is a fragment stack mechanism, the discontinuous virtual memory space is mapped to "continuous" in XX units of the stack space provided to the program. Just as the next layer of conversion is done by page break, the previous layer is through the stack out of bounds detection plus go run time library to complete, specifically do not expand, anyway, we can think of it as another form of "page break."
Well, now it's clear. Setting the Goroutine initial stack size to 4k does not reduce the "page break" of our upper layer, and if goroutine generally uses more stack space than this value, it will only make the allocation and release of the upper layer more frequent. On the other hand, this value is set to 8k, also does not necessarily increase the bottom of the fault, because the application of 8k of memory, if you do not use so much, actually will not cause the fault of the fault, resulting in the allocation of physical memory.
Then the person in front said, a connection to open a goroutine, memory use will be overturned, in fact, it is not so exaggerated. Memory usage can certainly improve, but it's worth it. You think, frequent "enough, then take, not enough, then take", and "take more points, save every time to toss", which kind of speed faster?
Well, if 8k is a reasonable 徝, why go ready to abandon the design of the segmented stack? Next look at the problem with the staging stack.
The staging stack automatically expands when the function needs a larger stack space, and is freed when the function is no longer needed. A very extreme case is that the stack size of a function's execution has been irresolute at the initial stack size boundary. Then it will constantly trigger the allocation and recycling of the segmented stack, and you can imagine how this is going to hurt.
Continuous stacks can avoid this problem. In the new implementation, an initial stack will be given to each goroutine, and when the stack is out of bounds, a larger memory space will be allocated as a new stack, and the old stack will be copied to the new stack.
This reminds me of a previously written toy code for a co-process, and also a stack copy. Did not test, oneself also did not end, only then saw Cloud wind big God also did so, did not think now go also want to do so.