操作系统 | 进程的内存映像

image-20250917144638764

image-20250917145737103

不同于存放在硬盘上的可执行程序文件,当一个程序调入内存运行时,就构成了进程的内存映像。一个进程的内存映像一般有几个要素:

  • 代码段:即程序的二进制代码,代码段是只读的,可以被多个进程共享。
  • 数据段:即程序运行时加工处理的对象,包括全局变量和静态变量。
  • 进程控制块(PCB):存放在系统区。操作系统通过PCB来控制和管理进程。
  • :用来存放动态分配的变量。通过调用malloc 函数动态地向高地址分配空间。
  • :用来实现函数调用。从用户空间的最大地址往低地址方向增长。

代码段和数据段在程序调入内存时就指定了大小,而堆和栈不一样。

当调用像malloc和free这样的C标准库函数时,堆可以在运行时动态地扩展和收缩。

用户栈在程序运行期间也可以动态地扩展和收缩,每次调用一个函数,栈就会增长;从一个函数返回时,栈就会收缩。

image-20250917145707573

批注:

1.未使用区的大小是固定的

2.堆的最高地址只能到0x40000000,也就是说堆和下面三块加起来的大小的和是固定的,只能有1GB。那么堆的最大有多大还要看下面三块有多大了。

3.const定义的存在只读代码区,但是define宏定义的不在。define的在编译代码时会直接被替换为指令中的立即数。

  1. 下图是一个进程在内存中的映像。

image-20230914155418540

  • 其中,共享库用来存放进程用到的共享函数库代码,如printf函数等。
  • 在只读代码段中,.iit是程序初始化时调用的_init函数;.text是用户程序的机器代码;.rodata是只读数据。
  • 在读/写数据段中,.data是已初始化的全局变量和静态变量;.bss是未初始化及所有初始化为0的全局变量和静态变量。