内存模型 Stack,Heap

Heap:

寄存器只能存放少量的数据,大多数的时候,CPU要指挥寄存器,直接跟内存交换数据。

程序运行的时候,操作系统会给它分配一段内存,用来存数和运行产生的数据。着端内存有起始地址和结束地址,

比如从0x1000到0x8000。

程序运行过程中,对于动态的内存占用请求(比如新建对象,或者使用malloc命令),系统就会从预先分配好的那段内存之中,划出一部分给用户,具体规则是从起始地址开始划分。比如用户要求得到10个字节内存,那么从起始地址0x1000开始给他分配,一直分配到地址0x100A。

这种因为用户主动请求而划分出来的内存区域,叫做Heap(堆)。它由起始地址开始,从低位地址向高位地址增长。

Heap的一个重要特点就是不会自动消失,必须手动释放,或者有垃圾回收机制来回收。

Stack:

除了 Heap 以外,其他的内存占用叫做 Stack(栈)。简单说,Stack 是由于函数运行而临时占用的内存区域。

举例:

int main{
    
     int a=2;
     int b=3;

}

上面代码中,系统开始执行main函数时,会为它在内存里面建立一个帧(frame),所有main的内部变量(比如ab)都保存在这个帧里面。main函数执行结束后,该帧就会被回收,释放所有的内部变量,不再占用空间。

如果函数内部调用了其他函数,会发生什么情况?

int main{
   int a=2;
   int b=3;
   return add_a_and_b(a,b)
}

上面代码中,main函数内部调用了add_a_and_b函数。执行到这一行的时候,系统也会为add_a_and_b新建一个帧,用来储存它的内部变量。也就是说,此时同时存在两个帧:mainadd_a_and_b。一般来说,调用栈有多少层,就有多少帧。

等到add_a_and_b运行结束,它的帧就会被回收,系统会回到函数main刚才中断执行的地方,继续往下执行。通过这种机制,就实现了函数的层层调用,并且每一层都能使用自己的本地变量。

所有的帧都存放在 Stack,由于帧是一层层叠加的,所以 Stack 叫做栈。生成新的帧,叫做"入栈",英文是 push;栈的回收叫做"出栈",英文是 pop。Stack 的特点就是,最晚入栈的帧最早出栈(因为最内层的函数调用,最先结束运行),这就叫做"后进先出"的数据结构。每一次函数执行结束,就自动释放一个帧,所有函数执行结束,整个 Stack 就都释放了。

Stack 是由内存区域的结束地址开始,从高位(地址)向低位(地址)分配。比如,内存区域的结束地址是0x8000,第一帧假定是16字节,那么下一次分配的地址就会从0x7FF0开始;第二帧假定需要64字节,那么地址就会移动到0x7FB0

转自:连接地址

猜你喜欢

转载自blog.csdn.net/tian5753/article/details/81089658
今日推荐