以下只是我个人自己学习理解的一些总结,会有很多很浅的地方,理解不对的地方。
一个进程在内存中布局分为:代码段,数据段,堆,共享库,栈,与操作系统通信部分。其中代码段和数据段来源于编译完成的可执行程序。共享库段是你程序运行的时候调用运行库和第三方共享库。操作系统通信部分-系统调用。
栈:就是操作系统中具有先入后出功能的一块内存。
栈保存了一个函数调用所需要维护的信息,被称为堆栈帧。一般保存函数的返回地址和参数。临时变量和保存上下文。然后就是用两个寄存器(类似游标来圈定范围)
一个函数调用另一个函数,是通过栈来传递参数的,调用方先把参数压入对应的栈中。而且参数调用一般是从右到左。
当一个函数拥有返回值的时候,其实先先把返回值复制个一个寄存器。调用方在从寄存器中去获取对应的值。但是这个寄存器是有大小,一般好像4个字节,所以当返回值比较大的话,其实是先从调用方栈中开发一个零时空间。传递给被调用方。然后先把返回值拷贝给这个临时变量,然后临时变量在地址在拷贝给寄存器。
堆:栈上的数据会随着函数结束消失,全局变量又不能动态生成。这就是堆的优势,可以动态生成的在程序员释放之前一直有效的内存区域。
其实我们程序员malloc的时候,并不是通过系统调用从操作系统内核中申请内存的。我们不过是向c语言运行时库去申请内存。c语言运行时库会一次通过系统调用申请一块大的内存,对于linux来说操作方式就是mmap。然后c语言运行时库会维护这一整块内存。通过空闲表呀,对象池,位图的方式管理,然后在零售给程序。当没有的时候 在去向操作系统去申请。
网友评论