Variables in our program are mostly allocated in two areas of memory: statck and heap.
stack
andheap
Let’s start with a review of process memory allocation: when we write program code, it runs as a process. OS allocates memory to our processes; The memory structure is roughly as follows:
The memory space allocated by the OS to a process can be roughly divided into six parts: code area, global data area, stack, heap, environment variable area and the middle blank buffer. Where, the growth path of data is from low to high except for the stack (see the data arrow in the figure).
Let’s think about it for a second, why is the stack so special as opposed to the rest of the stack? The stack and heap names in the process memory are the same as the stack and heap names in the data structure. Read on with your questions:
In process memorystack
andheap
Stack: the program side applies for the operating system through system calls. The operating system manages and releases the stack without manual management by the programmer. Generally used to store temporary variables generated in threads and functions. The data in this area can be used quickly without manual management, saving worry and effort.
Heap: an area of memory that is requested from the operating system by the program side through system calls, but requires programmer management because this area is located as global variable, used to store global variables (although not used in many programming languages); Programmers need to free or delete data in this memory area manually or via GC, but be aware that frequent deletes and additions can lead to memory fragmentation.
The data structurestack
andheap
Let’s look at stack and heap in data structures;
stack
LIFO’s LIFO data structure.
Heap
Definition of heap:
- Complete binary tree
- The value of each node must be greater than or equal to (or less than or equal to) the value of each node in its child tree
Those with the largest root are called “big top heaps” and those with the smallest are called “small top heaps”.
Heap data structure is often used in “how to quickly locate and obtain the hottest XXX in the Top N”, usually as shown in the following figure:
In memory”stack
andheap
“And in the data structure”stack
andheap
“The link
In summary: the stack in process memory uses the same data structure as the stack, and the heap in memory has nothing to do with the heap in the data structure.
Take a look at the following C code:
int main(a) {
int a = 3;
int b = 5;
ret = add(a, b);
printf("%d", ret);
reuturn 0;
}
int add(int x, int y) {
int sum = 0;
sum = x + y;
return sum;
}
Copy the code
The data in the stack looks like this:
Also can be mentioned above: “process memory only stack (stack) data from high to low growth, the rest are low to high growth?”
The data structure used by stack area is stack, and the sequence of destruction and return of function variables is exactly in line with the characteristics of stack first and then out. I think this is a very important point for stack area reverse growth.
However, the most fundamental reason is still: the legacy of history. See the picture below:
Back in the days when memory was scarce, do you think the left picture or the right picture was more suitable for the “buffer”? becausestack
Regional andheap
The size of the region is dynamically allocated, and there is “uncertainty”, which obviously happens on the leftThe stack of overlapping
Smaller and better suited to full memory utilization.
The position of the Go variable
When writing C, PHP, Java, etc., we can easily know the location of the variable: new, malloc, etc., that must be allocated on the heap, and how to handle the subsequent GC, whether the reference continues to be associated, whether the heap is released, whether the program has a memory leak. It’s all a matter of follow-up; The storage location of variables is no problem on the heap. However, when using Go, pay attention to the keyword, new, make and so on are not good, Go variable position is not determined by the programmer, but Go itself; So maybe your variable comes out new, but it doesn’t necessarily end up on the heap, it might end up on the stack.
Go “hides” where variables are from the programmer, and takes care of it; Because Go believes that the storage location of variables will have a certain impact on the performance of the program, and Go plans to build a program with extreme requirements on performance, so it takes care of itself. First of all, it is common sense that the stack is more efficient than the heap. Go evaluates each function variable at compile time. If it cannot determine whether the variable in the function is still referenced after the return, it is thrown on the heap, otherwise, it is thrown on the stack. But note that if the variable is very large, it will still be thrown on the heap.
Escape analysis
Is there any way to know where the variables are in the Go program we wrote? The answer is yes, Go provides developers with tools for variable escape analysis
go build -gcflags '-m -l' main.go // Here main.go can also be a specific binary application
Copy the code
Escape analysis is performed for the following code:
import (
"fmt"
)
func main(a){
a:= 3
b := 5
ret := add(a, b)
fmt.Println(ret)
}
func add(x,y int)int {
sum := x + y
return sum
}
Copy the code
Analysis results:
./main.go:11:16: main ... argument does not escape
./main.go:11:16: ret escapes to heap
Copy the code